deal.II version GIT relicensing-2291-g668cd86249 2024-12-24 11: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\}}\)
Loading...
Searching...
No Matches
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
20#include <type_traits>
21
23
24
25namespace Differentiation
26{
27 namespace AD
28 {
34 template <typename NumberType, typename = void>
35 struct is_adolc_number : std::false_type
36 {};
37
38
44 template <typename NumberType, typename = void>
45 struct is_adolc_taped_number : std::false_type
46 {};
47
48
54 template <typename NumberType, typename = void>
55 struct is_adolc_tapeless_number : std::false_type
56 {};
57 } // namespace AD
58} // namespace Differentiation
59
60
62
63
64#ifdef DEAL_II_WITH_ADOLC
65
67# include <deal.II/base/numbers.h>
68
71
72# include <adolc/adouble.h> // Taped double
73# include <adolc/adtl.h> // Tapeless double
74# include <adolc/internal/adolc_settings.h>
75# include <adolc/internal/adubfunc.h> // Taped double math functions
76
77# include <complex>
78# include <limits>
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 std::enable_if_t<std::is_floating_point_v<ScalarType>>>
114 {
115 static const bool is_taped = true;
116 using real_type = adouble;
117 using derivative_type = double;
118 static const unsigned int n_supported_derivative_levels =
119 std::numeric_limits<unsigned int>::max();
120 };
121
122
127 template <typename ScalarType>
128 struct ADNumberInfoFromEnum<
129 ScalarType,
131 std::enable_if_t<std::is_floating_point_v<ScalarType>>>
132 {
133 static const bool is_taped = false;
134 using real_type = adtl::adouble;
135 using derivative_type = double;
136 static const unsigned int n_supported_derivative_levels = 1;
137 };
138
139
140 template <typename ADNumberType>
141 struct Marking<
142 ADNumberType,
143 std::enable_if_t<ADNumberTraits<ADNumberType>::type_code ==
144 NumberTypes::adolc_taped &&
145 ADNumberTraits<ADNumberType>::is_real_valued>>
146 {
147 using scalar_type = typename ADNumberTraits<ADNumberType>::scalar_type;
148
149 /*
150 * Initialize the state of an independent variable.
151 */
152 static void
153 independent_variable(const scalar_type &in,
154 const unsigned int,
155 const unsigned int,
156 ADNumberType &out)
157 {
158 out <<= in;
159 }
160
161 /*
162 * Initialize the state of a dependent variable.
163 *
164 * @note The second argument must be writable, so we
165 * simply pass a copy instead of a non-constant reference.
166 */
167 static void
168 dependent_variable(ADNumberType &out, ADNumberType func)
169 {
170 // Store the value only (strip it of all sensitivities)
171 out = ADNumberTraits<ADNumberType>::get_scalar_value(func);
172 // Mark as a dependent variable
173 scalar_type tmp;
174 func >>= tmp;
175 }
176 };
177
178 template <typename ADNumberType>
179 struct Marking<
180 ADNumberType,
181 std::enable_if_t<ADNumberTraits<ADNumberType>::type_code ==
182 NumberTypes::adolc_tapeless &&
183 ADNumberTraits<ADNumberType>::is_real_valued>>
184 {
185 using scalar_type = typename ADNumberTraits<ADNumberType>::scalar_type;
186
187 /*
188 * Initialize the state of an independent variable.
189 */
190 static void
191 independent_variable(const scalar_type &in,
192 const unsigned int index,
193 const unsigned int,
194 ADNumberType &out)
195 {
196 // It is important that the tapeless variables have their values set
197 // before defining their directional derivative index
198 out = in;
199
200 // Violating this condition when will result in an ADOL-C internal
201 // error. We could rather always throw here in order to provide a
202 // less cryptic message.
203 AssertThrow(index < adtl::getNumDir(),
205 "The index number of the independent variable being "
206 "marked is greater than the number of independent "
207 "variables that have been declared."));
208 out.setADValue(index, 1 /*seed value for first derivative*/);
209 }
210
211 /*
212 * Initialize the state of a dependent variable.
213 */
214 static void
215 dependent_variable(ADNumberType &out, const ADNumberType &func)
216 {
217 // Simply transfer value with sensitivities
218 out = 0.0;
219 out = func;
220 }
221 };
222
223
228 template <>
229 struct ExtractData<adouble>
230 {
234 static double
235 value(const adouble &x)
236 {
237 return x.getValue();
238 }
239
240
247 static unsigned int
248 n_directional_derivatives(const adouble &)
249 {
250 return 0;
251 }
252
253
261 static double
262 directional_derivative(const adouble &, const unsigned int)
263 {
264 AssertThrow(false,
266 "The derivative values for taped ADOL-C numbers must be"
267 " computed through the ::gradient function."));
268 return 0.0;
269 }
270 };
271
272
277 template <>
278 struct ExtractData<adtl::adouble>
279 {
283 static double
284 value(const adtl::adouble &x)
285 {
286 return x.getValue();
287 }
288
289
293 static unsigned int
294 n_directional_derivatives(const adtl::adouble &)
295 {
296 // This is a global function call...
297 return adtl::getNumDir();
298 }
299
300
304 static double
305 directional_derivative(const adtl::adouble &x,
306 const unsigned int direction)
307 {
308 Assert(
309 direction < n_directional_derivatives(x),
311 "Requested directional derivative is greater than the number "
312 "registered by ADOL-C."));
313 return x.getADValue(direction);
314 }
315 };
316
317 } // namespace internal
318
319
320
329 template <typename ADNumberType>
330 struct ADNumberTraits<
331 ADNumberType,
332 std::enable_if_t<std::is_same_v<ADNumberType, adouble>>>
333 : NumberTraits<double, NumberTypes::adolc_taped>
334 {
335 static_assert(std::is_same_v<ad_type, adouble>,
336 "Incorrect template type selected for taped ad_type");
337 static_assert(is_taped == true, "Incorrect setting for taping");
338 };
339
340
341
351 template <typename ADNumberType>
352 struct ADNumberTraits<
353 ADNumberType,
354 std::enable_if_t<std::is_same_v<ADNumberType, std::complex<adouble>>>>
355 : NumberTraits<std::complex<double>, NumberTypes::adolc_taped>
356 {
357 static_assert(std::is_same_v<ad_type, std::complex<adouble>>,
358 "Incorrect template type selected for taped ad_type");
359 static_assert(is_taped == true, "Incorrect setting for taping");
360 };
361
362
363
372 template <typename ADNumberType>
373 struct ADNumberTraits<
374 ADNumberType,
375 std::enable_if_t<std::is_same_v<ADNumberType, adtl::adouble>>>
376 : NumberTraits<double, NumberTypes::adolc_tapeless>
377 {
378 static_assert(std::is_same_v<ad_type, adtl::adouble>,
379 "Incorrect template type selected for tapeless ad_type");
380 static_assert(is_tapeless == true, "Incorrect setting for taping");
381 };
382
383
384
394 template <typename ADNumberType>
395 struct ADNumberTraits<
396 ADNumberType,
397 std::enable_if_t<
398 std::is_same_v<ADNumberType, std::complex<adtl::adouble>>>>
399 : NumberTraits<std::complex<double>, NumberTypes::adolc_tapeless>
400 {
401 static_assert(std::is_same_v<ad_type, std::complex<adtl::adouble>>,
402 "Incorrect template type selected for tapeless ad_type");
403 static_assert(is_tapeless == true, "Incorrect setting for taping");
404 };
405
406
407
412 template <>
413 struct NumberTraits<adouble, NumberTypes::adolc_taped>
414 : NumberTraits<typename ADNumberTraits<adouble>::scalar_type,
415 NumberTypes::adolc_taped>
416 {};
417
418
423 template <>
424 struct NumberTraits<std::complex<adouble>, NumberTypes::adolc_taped>
425 : NumberTraits<
426 typename ADNumberTraits<std::complex<adouble>>::scalar_type,
427 NumberTypes::adolc_taped>
428 {};
429
430
435 template <>
436 struct NumberTraits<adtl::adouble, NumberTypes::adolc_tapeless>
437 : NumberTraits<typename ADNumberTraits<adtl::adouble>::scalar_type,
438 NumberTypes::adolc_tapeless>
439 {};
440
441
446 template <>
447 struct NumberTraits<std::complex<adtl::adouble>,
449 : NumberTraits<
450 typename ADNumberTraits<std::complex<adtl::adouble>>::scalar_type,
451 NumberTypes::adolc_tapeless>
452 {};
453
454
459 template <typename NumberType>
460 struct is_adolc_taped_number<
461 NumberType,
462 std::enable_if_t<ADNumberTraits<std::decay_t<NumberType>>::type_code ==
463 NumberTypes::adolc_taped>> : std::true_type
464 {};
465
466
471 template <typename NumberType>
472 struct is_adolc_tapeless_number<
473 NumberType,
474 std::enable_if_t<ADNumberTraits<std::decay_t<NumberType>>::type_code ==
475 NumberTypes::adolc_tapeless>> : std::true_type
476 {};
477
478
483 template <typename NumberType>
484 struct is_adolc_number<
485 NumberType,
486 std::enable_if_t<is_adolc_taped_number<NumberType>::value ||
487 is_adolc_tapeless_number<NumberType>::value>>
488 : std::true_type
489 {};
490
491 } // namespace AD
492} // namespace Differentiation
493
494
495# endif // DOXYGEN
496
497
499
500
501#endif // DEAL_II_WITH_ADOLC
502
503#endif
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:498
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:499
#define Assert(cond, exc)
#define DeclExceptionMsg(Exception, defaulttext)
Definition exceptions.h:489
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
static ::ExceptionBase & ExcADOLCAdvancedBranching()
Definition numbers.h:48
STL namespace.