Loading [MathJax]/extensions/TeX/newcommand.js
 deal.II version GIT relicensing-3110-g10dd77059b 2025-04-22 10:30:00+00:00
\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\}}
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
adolc_number_types.h
Go to the documentation of this file.
1// ------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: LGPL-2.1-or-later
4// Copyright (C) 2017 - 2023 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Part of the source code is dual licensed under Apache-2.0 WITH
9// LLVM-exception OR LGPL-2.1-or-later. Detailed license information
10// governing the source code and code contributions can be found in
11// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II.
12//
13// ------------------------------------------------------------------------
14
15#ifndef dealii_differentiation_ad_adolc_number_types_h
16#define dealii_differentiation_ad_adolc_number_types_h
17
18#include <deal.II/base/config.h>
19
22
25
26#ifdef DEAL_II_WITH_ADOLC
27# include <adolc/adouble.h> // Taped double
28# include <adolc/adtl.h> // Tapeless double
29# include <adolc/internal/adolc_settings.h>
30# include <adolc/internal/adubfunc.h> // Taped double math functions
31#endif
32
33#include <complex>
34#include <limits>
35#include <type_traits>
36
37
39
40
41namespace Differentiation
42{
43 namespace AD
44 {
50 template <typename NumberType, typename = void>
51 struct is_adolc_number : std::false_type
52 {};
53
54
60 template <typename NumberType, typename = void>
61 struct is_adolc_taped_number : std::false_type
62 {};
63
64
70 template <typename NumberType, typename = void>
71 struct is_adolc_tapeless_number : std::false_type
72 {};
73 } // namespace AD
74} // namespace Differentiation
75
76
77
78#ifdef DEAL_II_WITH_ADOLC
79
87 "This function has not yet been implemented for taped ADOL-C "
88 "numbers when the advanced branching feature is activated.");
89
90
91/* ----------- inline and template functions and specializations ----------- */
92
93
94# ifndef DOXYGEN
95
96
97namespace Differentiation
98{
99 namespace AD
100 {
101 namespace internal
102 {
107 template <typename ScalarType>
108 struct ADNumberInfoFromEnum<
109 ScalarType,
111 std::enable_if_t<std::is_floating_point_v<ScalarType>>>
112 {
113 static const bool is_taped = true;
114 using real_type = adouble;
115 using derivative_type = double;
116 static const unsigned int n_supported_derivative_levels =
117 std::numeric_limits<unsigned int>::max();
118 };
119
120
125 template <typename ScalarType>
126 struct ADNumberInfoFromEnum<
127 ScalarType,
129 std::enable_if_t<std::is_floating_point_v<ScalarType>>>
130 {
131 static const bool is_taped = false;
132 using real_type = adtl::adouble;
133 using derivative_type = double;
134 static const unsigned int n_supported_derivative_levels = 1;
135 };
136
137
138 template <typename ADNumberType>
139 struct Marking<
140 ADNumberType,
141 std::enable_if_t<ADNumberTraits<ADNumberType>::type_code ==
142 NumberTypes::adolc_taped &&
143 ADNumberTraits<ADNumberType>::is_real_valued>>
144 {
145 using scalar_type = typename ADNumberTraits<ADNumberType>::scalar_type;
146
147 /*
148 * Initialize the state of an independent variable.
149 */
150 static void
151 independent_variable(const scalar_type &in,
152 const unsigned int,
153 const unsigned int,
154 ADNumberType &out)
155 {
156 out <<= in;
157 }
158
159 /*
160 * Initialize the state of a dependent variable.
161 *
162 * @note The second argument must be writable, so we
163 * simply pass a copy instead of a non-constant reference.
164 */
165 static void
166 dependent_variable(ADNumberType &out, ADNumberType func)
167 {
168 // Store the value only (strip it of all sensitivities)
169 out = ADNumberTraits<ADNumberType>::get_scalar_value(func);
170 // Mark as a dependent variable
171 scalar_type tmp;
172 func >>= tmp;
173 }
174 };
175
176 template <typename ADNumberType>
177 struct Marking<
178 ADNumberType,
179 std::enable_if_t<ADNumberTraits<ADNumberType>::type_code ==
180 NumberTypes::adolc_tapeless &&
181 ADNumberTraits<ADNumberType>::is_real_valued>>
182 {
183 using scalar_type = typename ADNumberTraits<ADNumberType>::scalar_type;
184
185 /*
186 * Initialize the state of an independent variable.
187 */
188 static void
189 independent_variable(const scalar_type &in,
190 const unsigned int index,
191 const unsigned int,
192 ADNumberType &out)
193 {
194 // It is important that the tapeless variables have their values set
195 // before defining their directional derivative index
196 out = in;
197
198 // Violating this condition when will result in an ADOL-C internal
199 // error. We could rather always throw here in order to provide a
200 // less cryptic message.
201 AssertThrow(index < adtl::getNumDir(),
203 "The index number of the independent variable being "
204 "marked is greater than the number of independent "
205 "variables that have been declared."));
206 out.setADValue(index, 1 /*seed value for first derivative*/);
207 }
208
209 /*
210 * Initialize the state of a dependent variable.
211 */
212 static void
213 dependent_variable(ADNumberType &out, const ADNumberType &func)
214 {
215 // Simply transfer value with sensitivities
216 out = 0.0;
217 out = func;
218 }
219 };
220
221
226 template <>
227 struct ExtractData<adouble>
228 {
232 static double
233 value(const adouble &x)
234 {
235 return x.getValue();
236 }
237
238
245 static unsigned int
246 n_directional_derivatives(const adouble &)
247 {
248 return 0;
249 }
250
251
259 static double
260 directional_derivative(const adouble &, const unsigned int)
261 {
262 AssertThrow(false,
264 "The derivative values for taped ADOL-C numbers must be"
265 " computed through the ::gradient function."));
266 return 0.0;
267 }
268 };
269
270
275 template <>
276 struct ExtractData<adtl::adouble>
277 {
281 static double
282 value(const adtl::adouble &x)
283 {
284 return x.getValue();
285 }
286
287
291 static unsigned int
292 n_directional_derivatives(const adtl::adouble &)
293 {
294 // This is a global function call...
295 return adtl::getNumDir();
296 }
297
298
302 static double
303 directional_derivative(const adtl::adouble &x,
304 const unsigned int direction)
305 {
306 Assert(
307 direction < n_directional_derivatives(x),
309 "Requested directional derivative is greater than the number "
310 "registered by ADOL-C."));
311 return x.getADValue(direction);
312 }
313 };
314
315 } // namespace internal
316
317
318
327 template <typename ADNumberType>
328 struct ADNumberTraits<
329 ADNumberType,
330 std::enable_if_t<std::is_same_v<ADNumberType, adouble>>>
331 : NumberTraits<double, NumberTypes::adolc_taped>
332 {
333 static_assert(std::is_same_v<ad_type, adouble>,
334 "Incorrect template type selected for taped ad_type");
335 static_assert(is_taped == true, "Incorrect setting for taping");
336 };
337
338
339
349 template <typename ADNumberType>
350 struct ADNumberTraits<
351 ADNumberType,
352 std::enable_if_t<std::is_same_v<ADNumberType, std::complex<adouble>>>>
353 : NumberTraits<std::complex<double>, NumberTypes::adolc_taped>
354 {
355 static_assert(std::is_same_v<ad_type, std::complex<adouble>>,
356 "Incorrect template type selected for taped ad_type");
357 static_assert(is_taped == true, "Incorrect setting for taping");
358 };
359
360
361
370 template <typename ADNumberType>
371 struct ADNumberTraits<
372 ADNumberType,
373 std::enable_if_t<std::is_same_v<ADNumberType, adtl::adouble>>>
374 : NumberTraits<double, NumberTypes::adolc_tapeless>
375 {
376 static_assert(std::is_same_v<ad_type, adtl::adouble>,
377 "Incorrect template type selected for tapeless ad_type");
378 static_assert(is_tapeless == true, "Incorrect setting for taping");
379 };
380
381
382
392 template <typename ADNumberType>
393 struct ADNumberTraits<
394 ADNumberType,
395 std::enable_if_t<
396 std::is_same_v<ADNumberType, std::complex<adtl::adouble>>>>
397 : NumberTraits<std::complex<double>, NumberTypes::adolc_tapeless>
398 {
399 static_assert(std::is_same_v<ad_type, std::complex<adtl::adouble>>,
400 "Incorrect template type selected for tapeless ad_type");
401 static_assert(is_tapeless == true, "Incorrect setting for taping");
402 };
403
404
405
410 template <>
411 struct NumberTraits<adouble, NumberTypes::adolc_taped>
412 : NumberTraits<typename ADNumberTraits<adouble>::scalar_type,
413 NumberTypes::adolc_taped>
414 {};
415
416
421 template <>
422 struct NumberTraits<std::complex<adouble>, NumberTypes::adolc_taped>
423 : NumberTraits<
424 typename ADNumberTraits<std::complex<adouble>>::scalar_type,
425 NumberTypes::adolc_taped>
426 {};
427
428
433 template <>
434 struct NumberTraits<adtl::adouble, NumberTypes::adolc_tapeless>
435 : NumberTraits<typename ADNumberTraits<adtl::adouble>::scalar_type,
436 NumberTypes::adolc_tapeless>
437 {};
438
439
444 template <>
445 struct NumberTraits<std::complex<adtl::adouble>,
447 : NumberTraits<
448 typename ADNumberTraits<std::complex<adtl::adouble>>::scalar_type,
449 NumberTypes::adolc_tapeless>
450 {};
451
452
457 template <typename NumberType>
458 struct is_adolc_taped_number<
459 NumberType,
460 std::enable_if_t<ADNumberTraits<std::decay_t<NumberType>>::type_code ==
461 NumberTypes::adolc_taped>> : std::true_type
462 {};
463
464
469 template <typename NumberType>
470 struct is_adolc_tapeless_number<
471 NumberType,
472 std::enable_if_t<ADNumberTraits<std::decay_t<NumberType>>::type_code ==
473 NumberTypes::adolc_tapeless>> : std::true_type
474 {};
475
476
481 template <typename NumberType>
482 struct is_adolc_number<
483 NumberType,
484 std::enable_if_t<is_adolc_taped_number<NumberType>::value ||
485 is_adolc_tapeless_number<NumberType>::value>>
486 : std::true_type
487 {};
488
489 } // namespace AD
490} // namespace Differentiation
491
492
493# endif // DOXYGEN
494
495
496#endif // DEAL_II_WITH_ADOLC
497
499
500
501#endif
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:35
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:36
#define Assert(cond, exc)
#define DeclExceptionMsg(Exception, defaulttext)
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
static ::ExceptionBase & ExcADOLCAdvancedBranching()
Definition numbers.h:34
STL namespace.