deal.II version GIT relicensing-6834-g5b78e6bcdf 2026-10-01 11:20:01+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\}}\)
Loading...
Searching...
No Matches
adolc_number_types.h
Go to the documentation of this file.
1// -----------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception OR LGPL-2.1-or-later
4// Copyright (C) 2017 - 2025 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Detailed license information governing the source code and contributions
9// can be found in LICENSE.md and CONTRIBUTING.md at the top level directory.
10//
11// -----------------------------------------------------------------------------
12
13#ifndef dealii_differentiation_ad_adolc_number_types_h
14#define dealii_differentiation_ad_adolc_number_types_h
15
16#include <deal.II/base/config.h>
17
20
23
24#ifdef DEAL_II_WITH_ADOLC
25# include <adolc/adouble.h> // Taped double
26# include <adolc/adtl.h> // Tapeless double
27# include <adolc/internal/adolc_settings.h>
28# include <adolc/internal/adubfunc.h> // Taped double math functions
29#endif
30
31#include <complex>
32#include <limits>
33#include <type_traits>
34
35
37
38
39namespace Differentiation
40{
41 namespace AD
42 {
48 template <typename NumberType, typename = void>
49 struct is_adolc_number : std::false_type
50 {};
51
52
58 template <typename NumberType, typename = void>
59 struct is_adolc_taped_number : std::false_type
60 {};
61
62
68 template <typename NumberType, typename = void>
69 struct is_adolc_tapeless_number : std::false_type
70 {};
71 } // namespace AD
72} // namespace Differentiation
73
74
75
76#ifdef DEAL_II_WITH_ADOLC
77
85 "This function has not yet been implemented for taped ADOL-C "
86 "numbers when the advanced branching feature is activated.");
87
88
89/* ----------- inline and template functions and specializations ----------- */
90
91
92# ifndef DOXYGEN
93
94
95namespace Differentiation
96{
97 namespace AD
98 {
99 namespace internal
100 {
105 template <typename ScalarType>
106 struct ADNumberInfoFromEnum<
107 ScalarType,
109 std::enable_if_t<std::is_floating_point_v<ScalarType>>>
110 {
111 static const bool is_taped = true;
112 using real_type = adouble;
113 using derivative_type = double;
114 static const unsigned int n_supported_derivative_levels =
115 std::numeric_limits<unsigned int>::max();
116 };
117
118
123 template <typename ScalarType>
124 struct ADNumberInfoFromEnum<
125 ScalarType,
127 std::enable_if_t<std::is_floating_point_v<ScalarType>>>
128 {
129 static const bool is_taped = false;
130 using real_type = adtl::adouble;
131 using derivative_type = double;
132 static const unsigned int n_supported_derivative_levels = 1;
133 };
134
135
136 template <typename ADNumberType>
137 struct Marking<
138 ADNumberType,
139 std::enable_if_t<ADNumberTraits<ADNumberType>::type_code ==
140 NumberTypes::adolc_taped &&
141 ADNumberTraits<ADNumberType>::is_real_valued>>
142 {
143 using scalar_type = typename ADNumberTraits<ADNumberType>::scalar_type;
144
145 /*
146 * Initialize the state of an independent variable.
147 */
148 static void
149 independent_variable(const scalar_type &in,
150 const unsigned int,
151 const unsigned int,
152 ADNumberType &out)
153 {
154 out <<= in;
155 }
156
157 /*
158 * Initialize the state of a dependent variable.
159 *
160 * @note The second argument must be writable, so we
161 * simply pass a copy instead of a non-constant reference.
162 */
163 static void
164 dependent_variable(ADNumberType &out, ADNumberType func)
165 {
166 // Store the value only (strip it of all sensitivities)
167 out = ADNumberTraits<ADNumberType>::get_scalar_value(func);
168 // Mark as a dependent variable
169 scalar_type tmp;
170 func >>= tmp;
171 }
172 };
173
174 template <typename ADNumberType>
175 struct Marking<
176 ADNumberType,
177 std::enable_if_t<ADNumberTraits<ADNumberType>::type_code ==
178 NumberTypes::adolc_tapeless &&
179 ADNumberTraits<ADNumberType>::is_real_valued>>
180 {
181 using scalar_type = typename ADNumberTraits<ADNumberType>::scalar_type;
182
183 /*
184 * Initialize the state of an independent variable.
185 */
186 static void
187 independent_variable(const scalar_type &in,
188 const unsigned int index,
189 const unsigned int,
190 ADNumberType &out)
191 {
192 // It is important that the tapeless variables have their values set
193 // before defining their directional derivative index
194 out = in;
195
196 // Violating this condition when will result in an ADOL-C internal
197 // error. We could rather always throw here in order to provide a
198 // less cryptic message.
199 AssertThrow(index < adtl::getNumDir(),
201 "The index number of the independent variable being "
202 "marked is greater than the number of independent "
203 "variables that have been declared."));
204 out.setADValue(index, 1 /*seed value for first derivative*/);
205 }
206
207 /*
208 * Initialize the state of a dependent variable.
209 */
210 static void
211 dependent_variable(ADNumberType &out, const ADNumberType &func)
212 {
213 // Simply transfer value with sensitivities
214 out = 0.0;
215 out = func;
216 }
217 };
218
219
224 template <>
225 struct ExtractData<adouble>
226 {
230 static double
231 value(const adouble &x)
232 {
233 return x.getValue();
234 }
235
236
243 static unsigned int
244 n_directional_derivatives(const adouble &)
245 {
246 return 0;
247 }
248
249
257 static double
258 directional_derivative(const adouble &, const unsigned int)
259 {
260 AssertThrow(false,
262 "The derivative values for taped ADOL-C numbers must be"
263 " computed through the ::gradient function."));
264 return 0.0;
265 }
266 };
267
268
273 template <>
274 struct ExtractData<adtl::adouble>
275 {
279 static double
280 value(const adtl::adouble &x)
281 {
282 return x.getValue();
283 }
284
285
289 static unsigned int
290 n_directional_derivatives(const adtl::adouble &)
291 {
292 // This is a global function call...
293 return adtl::getNumDir();
294 }
295
296
300 static double
301 directional_derivative(const adtl::adouble &x,
302 const unsigned int direction)
303 {
304 Assert(
305 direction < n_directional_derivatives(x),
307 "Requested directional derivative is greater than the number "
308 "registered by ADOL-C."));
309 return x.getADValue(direction);
310 }
311 };
312
313 } // namespace internal
314
315
316
325 template <typename ADNumberType>
326 struct ADNumberTraits<
327 ADNumberType,
328 std::enable_if_t<std::is_same_v<ADNumberType, adouble>>>
329 : NumberTraits<double, NumberTypes::adolc_taped>
330 {
331 static_assert(std::is_same_v<ad_type, adouble>,
332 "Incorrect template type selected for taped ad_type");
333 static_assert(is_taped, "Incorrect setting for taping");
334 };
335
336
337
347 template <typename ADNumberType>
348 struct ADNumberTraits<
349 ADNumberType,
350 std::enable_if_t<std::is_same_v<ADNumberType, std::complex<adouble>>>>
351 : NumberTraits<std::complex<double>, NumberTypes::adolc_taped>
352 {
353 static_assert(std::is_same_v<ad_type, std::complex<adouble>>,
354 "Incorrect template type selected for taped ad_type");
355 static_assert(is_taped, "Incorrect setting for taping");
356 };
357
358
359
368 template <typename ADNumberType>
369 struct ADNumberTraits<
370 ADNumberType,
371 std::enable_if_t<std::is_same_v<ADNumberType, adtl::adouble>>>
372 : NumberTraits<double, NumberTypes::adolc_tapeless>
373 {
374 static_assert(std::is_same_v<ad_type, adtl::adouble>,
375 "Incorrect template type selected for tapeless ad_type");
376 static_assert(is_tapeless, "Incorrect setting for taping");
377 };
378
379
380
390 template <typename ADNumberType>
391 struct ADNumberTraits<
392 ADNumberType,
393 std::enable_if_t<
394 std::is_same_v<ADNumberType, std::complex<adtl::adouble>>>>
395 : NumberTraits<std::complex<double>, NumberTypes::adolc_tapeless>
396 {
397 static_assert(std::is_same_v<ad_type, std::complex<adtl::adouble>>,
398 "Incorrect template type selected for tapeless ad_type");
399 static_assert(is_tapeless, "Incorrect setting for taping");
400 };
401
402
403
408 template <>
409 struct NumberTraits<adouble, NumberTypes::adolc_taped>
410 : NumberTraits<typename ADNumberTraits<adouble>::scalar_type,
411 NumberTypes::adolc_taped>
412 {};
413
414
419 template <>
420 struct NumberTraits<std::complex<adouble>, NumberTypes::adolc_taped>
421 : NumberTraits<
422 typename ADNumberTraits<std::complex<adouble>>::scalar_type,
423 NumberTypes::adolc_taped>
424 {};
425
426
431 template <>
432 struct NumberTraits<adtl::adouble, NumberTypes::adolc_tapeless>
433 : NumberTraits<typename ADNumberTraits<adtl::adouble>::scalar_type,
434 NumberTypes::adolc_tapeless>
435 {};
436
437
442 template <>
443 struct NumberTraits<std::complex<adtl::adouble>,
445 : NumberTraits<
446 typename ADNumberTraits<std::complex<adtl::adouble>>::scalar_type,
447 NumberTypes::adolc_tapeless>
448 {};
449
450
455 template <typename NumberType>
456 struct is_adolc_taped_number<
457 NumberType,
458 std::enable_if_t<ADNumberTraits<std::decay_t<NumberType>>::type_code ==
459 NumberTypes::adolc_taped>> : std::true_type
460 {};
461
462
467 template <typename NumberType>
468 struct is_adolc_tapeless_number<
469 NumberType,
470 std::enable_if_t<ADNumberTraits<std::decay_t<NumberType>>::type_code ==
471 NumberTypes::adolc_tapeless>> : std::true_type
472 {};
473
474
479 template <typename NumberType>
480 struct is_adolc_number<
481 NumberType,
482 std::enable_if_t<is_adolc_taped_number<NumberType>::value ||
483 is_adolc_tapeless_number<NumberType>::value>>
484 : std::true_type
485 {};
486
487 } // namespace AD
488} // namespace Differentiation
489
490
491# endif // DOXYGEN
492
493
494#endif // DEAL_II_WITH_ADOLC
495
497
498
499#endif
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
#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.