Reference documentation for deal.II version 9.4.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
26namespace 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
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
99namespace Differentiation
100{
101 namespace AD
102 {
103 namespace internal
104 {
109 template <typename ScalarType>
110 struct ADNumberInfoFromEnum<
111 ScalarType,
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,
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)
173 out = ADNumberTraits<ADNumberType>::get_scalar_value(func);
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(),
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,
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),
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>
477 struct is_adolc_tapeless_number<
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 DEAL_II_NAMESPACE_OPEN
Definition: config.h:442
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:443
#define Assert(cond, exc)
Definition: exceptions.h:1473
#define DeclExceptionMsg(Exception, defaulttext)
Definition: exceptions.h:487
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
Definition: exceptions.h:1583
static ::ExceptionBase & ExcADOLCAdvancedBranching()
STL namespace.