deal.II version GIT relicensing-2167-g9622207b8f 2024-11-21 12:40: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
ad_number_traits.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_ad_number_traits_h
16#define dealii_differentiation_ad_ad_number_traits_h
17
18#include <deal.II/base/config.h>
19
22
24
25#include <boost/type_traits.hpp>
26
27#include <complex>
28#include <type_traits>
29
31
32namespace Differentiation
33{
34 namespace AD
35 {
47 template <typename ScalarType,
48 enum NumberTypes ADNumberTypeCode,
49 typename T = void>
51
52
53
66 template <typename ADNumberType, typename T = void>
68
69
74 namespace internal
75 {
76 // The following three classes, namely ADNumberInfoFromEnum, Marking, and
77 // ExtractData, are those that need to be implemented for each new
78 // auto-differentiable number type. This information is then used by
79 // NumberTraits and ADNumberTraits to provide a uniform interface, as used
80 // by our drivers, to the underlying number types.
81
82
106 template <typename ScalarType,
107 enum NumberTypes ADNumberTypeCode,
108 typename = void>
110
111
141 template <typename ADNumberType, typename T = void>
142 struct Marking;
143
144
174 template <typename ADNumberType, typename T = void>
176
177
190 template <typename ADNumberTrait, typename T = void>
192
193
208 template <typename T>
209 struct NumberType;
210
211
216 template <typename Number>
218
219 } // namespace internal
220
221
228 template <typename NumberType>
229 struct is_ad_number;
230
231
238 template <typename NumberType, typename = void>
240
241
248 template <typename NumberType, typename = void>
250
251
258 template <typename NumberType, typename = void>
260
261
268 template <typename NumberType, typename = void>
270
271 } // namespace AD
272} // namespace Differentiation
273
274
275/* ----------- inline and template functions and specializations ----------- */
276
277
278#ifndef DOXYGEN
279
280
281namespace Differentiation
282{
283 namespace AD
284 {
285 namespace internal
286 {
287 template <typename ADNumberTrait, typename>
288 struct HasRequiredADInfo : std::false_type
289 {};
290
291
303 template <typename ADNumberTrait>
304 struct HasRequiredADInfo<
305 ADNumberTrait,
306 decltype((void)ADNumberTrait::type_code,
307 (void)ADNumberTrait::is_taped,
308 (void)std::declval<typename ADNumberTrait::real_type>(),
309 (void)std::declval<typename ADNumberTrait::derivative_type>(),
310 void())>
311 : std::conditional_t<
312 std::is_floating_point_v<typename ADNumberTrait::real_type>,
313 std::false_type,
314 std::true_type>
315 {};
316
317
322 template <typename ScalarType>
323 struct ADNumberInfoFromEnum<
324 ScalarType,
326 std::enable_if_t<std::is_floating_point_v<ScalarType>>>
327 {
328 static const bool is_taped = false;
329 using real_type = ScalarType;
330 using derivative_type = ScalarType;
331 static const unsigned int n_supported_derivative_levels = 0;
332 };
333
334
340 template <typename ScalarType>
341 struct Marking<ScalarType,
342 std::enable_if_t<std::is_floating_point_v<ScalarType>>>
343 {
351 template <typename ADNumberType>
352 static void
353 independent_variable(const ScalarType &in,
354 const unsigned int,
355 const unsigned int,
356 ADNumberType &out)
357 {
358 out = in;
359 }
360
361 /*
362 * Initialize the state of a dependent variable.
363 */
364 template <typename ADNumberType>
365 static void
366 dependent_variable(ADNumberType &, const ScalarType &)
367 {
369 false,
371 "Floating point numbers cannot be marked as dependent variables."));
372 }
373 };
374
375
379 template <typename ADNumberType>
380 struct Marking<ADNumberType,
381 std::enable_if_t<boost::is_complex<ADNumberType>::value>>
382 {
383 /*
384 * Initialize the state of an independent variable.
385 */
386 template <typename ScalarType>
387 static void
388 independent_variable(const ScalarType &in,
389 const unsigned int,
390 const unsigned int,
391 ADNumberType &out)
392 {
394 false,
396 "Marking for complex numbers has not yet been implemented."));
397 out = in;
398 }
399
400 /*
401 * Initialize the state of a dependent variable.
402 */
403 template <typename ScalarType>
404 static void
405 dependent_variable(ADNumberType &, const ScalarType &)
406 {
408 false,
410 "Marking for complex numbers has not yet been implemented."));
411 }
412 };
413
414 } // namespace internal
415
416
417 template <typename NumberType, typename>
418 struct is_taped_ad_number : std::false_type
419 {};
420
421
422 template <typename NumberType, typename>
423 struct is_tapeless_ad_number : std::false_type
424 {};
425
426
427 template <typename NumberType, typename>
428 struct is_real_valued_ad_number : std::false_type
429 {};
430
431
432 template <typename NumberType, typename>
433 struct is_complex_valued_ad_number : std::false_type
434 {};
435
436
442 template <typename NumberType>
443 struct is_ad_number
444 : internal::HasRequiredADInfo<ADNumberTraits<std::decay_t<NumberType>>>
445 {};
446
447
452 template <typename NumberType>
453 struct is_taped_ad_number<
454 NumberType,
455 std::enable_if_t<ADNumberTraits<std::decay_t<NumberType>>::is_taped>>
456 : std::true_type
457 {};
458
459
464 template <typename NumberType>
465 struct is_tapeless_ad_number<
466 NumberType,
467 std::enable_if_t<ADNumberTraits<std::decay_t<NumberType>>::is_tapeless>>
468 : std::true_type
469 {};
470
471
477 template <typename NumberType>
478 struct is_real_valued_ad_number<
479 NumberType,
480 std::enable_if_t<
481 ADNumberTraits<std::decay_t<NumberType>>::is_real_valued>>
482 : std::true_type
483 {};
484
485
491 template <typename NumberType>
492 struct is_complex_valued_ad_number<
493 NumberType,
494 std::enable_if_t<
495 ADNumberTraits<std::decay_t<NumberType>>::is_complex_valued>>
496 : std::true_type
497 {};
498
499
500 namespace internal
501 {
506 template <typename Number>
507 struct RemoveComplexWrapper
508 {
509 using type = Number;
510 };
511
512
518 template <typename Number>
519 struct RemoveComplexWrapper<std::complex<Number>>
520 {
521 using type = typename RemoveComplexWrapper<Number>::type;
522 };
523
524
530 template <typename NumberType>
531 struct ExtractData<NumberType,
532 std::enable_if_t<std::is_floating_point_v<NumberType>>>
533 {
537 static const NumberType &
538 value(const NumberType &x)
539 {
540 return x;
541 }
542
543
547 static unsigned int
548 n_directional_derivatives(const NumberType &)
549 {
550 return 0;
551 }
552
553
557 static NumberType
558 directional_derivative(const NumberType &, const unsigned int)
559 {
560 return 0.0;
561 }
562 };
563
564
565
570 template <typename ADNumberType>
571 struct ExtractData<std::complex<ADNumberType>>
572 {
574 "Expected an auto-differentiable number.");
575
576
580 static std::complex<typename ADNumberTraits<ADNumberType>::scalar_type>
581 value(const std::complex<ADNumberType> &x)
582 {
583 return std::complex<
584 typename ADNumberTraits<ADNumberType>::scalar_type>(
585 ExtractData<ADNumberType>::value(x.real()),
586 ExtractData<ADNumberType>::value(x.imag()));
587 }
588
589
593 static unsigned int
594 n_directional_derivatives(const std::complex<ADNumberType> &x)
595 {
596 return ExtractData<ADNumberType>::n_directional_derivatives(x.real());
597 }
598
599
603 static std::complex<
604 typename ADNumberTraits<ADNumberType>::derivative_type>
605 directional_derivative(const std::complex<ADNumberType> &x,
606 const unsigned int direction)
607 {
608 return std::complex<
609 typename ADNumberTraits<ADNumberType>::derivative_type>(
610 ExtractData<ADNumberType>::directional_derivative(x.real(),
611 direction),
612 ExtractData<ADNumberType>::directional_derivative(x.imag(),
613 direction));
614 }
615 };
616
617
618 template <typename T>
619 struct NumberType
620 {
624 template <typename F>
625 static auto
626 value(const F &f, std::enable_if_t<!is_ad_number<F>::value> * = nullptr)
628 {
629 // We call the other function defined in the numbers
630 // header to take care of all of the usual cases.
631 return ::internal::NumberType<T>::value(f);
632 }
633
640 template <typename F>
641 static T
642 value(const F &f,
643 std::enable_if_t<is_ad_number<F>::value &&
644 std::is_floating_point_v<T>> * = nullptr)
645 {
646 // We recursively call this function in case the AD number is a
647 // nested one. The recursion ends when the extracted value is
648 // a floating point number.
649 return NumberType<T>::value(ExtractData<F>::value(f));
650 }
651
658 template <typename F>
659 static T
660 value(const F &f,
661 std::enable_if_t<is_ad_number<F>::value && is_ad_number<T>::value>
662 * = nullptr)
663 {
664 return T(f);
665 }
666 };
667
668 template <typename T>
669 struct NumberType<std::complex<T>>
670 {
674 template <typename F>
675 static auto
676 value(const F &f, std::enable_if_t<!is_ad_number<F>::value> * = nullptr)
677 -> decltype(::internal::NumberType<std::complex<T>>::value(f))
678 {
679 // We call the other function defined in the numbers
680 // header to take care of all of the usual cases.
681 return ::internal::NumberType<std::complex<T>>::value(f);
682 }
683
684
689 template <typename F>
690 static std::complex<T>
691 value(const F &f,
692 std::enable_if_t<is_ad_number<F>::value &&
693 std::is_floating_point_v<T>> * = nullptr)
694 {
695 // We recursively call this function in case the AD number is a
696 // nested one. The recursion ends when the extracted value is
697 // a floating point number.
698 return std::complex<T>(
699 NumberType<T>::value(ExtractData<F>::value(f)));
700 }
701
702 template <typename F>
703 static std::complex<T>
704 value(const std::complex<F> &f)
705 {
706 // Deal with the two parts of the input complex
707 // number individually.
708 return std::complex<T>(NumberType<T>::value(f.real()),
709 NumberType<T>::value(f.imag()));
710 }
711 };
712
713 } // namespace internal
714
715
716
737 template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
738 struct NumberTraits<
739 ScalarType,
740 ADNumberTypeCode,
741 std::enable_if_t<
742 std::is_floating_point_v<ScalarType> ||
743 (boost::is_complex<ScalarType>::value &&
744 std::is_floating_point_v<
745 typename internal::RemoveComplexWrapper<ScalarType>::type>)>>
746 {
750 static constexpr enum NumberTypes type_code = ADNumberTypeCode;
751
752 // The clang compiler does not seem to like these
753 // variables being defined as constant expressions
754 // (the tests <adolc|sacado>/ad_number_traits_02 will
755 // fail with linking errors). However, GCC complains
756 // about the use of non-constant expressions in
757 // std::conditional.
758# ifdef __clang__
759
764 static const bool is_taped;
765
766
771 static const bool is_tapeless;
772
773
778 static const bool is_real_valued;
779
780
785 static const bool is_complex_valued;
786
787
792 static const unsigned int n_supported_derivative_levels;
793
794# else
795
800 static constexpr bool is_taped = internal::ADNumberInfoFromEnum<
801 typename internal::RemoveComplexWrapper<ScalarType>::type,
802 ADNumberTypeCode>::is_taped;
803
804
809 static constexpr bool is_tapeless =
810 !(NumberTraits<ScalarType, ADNumberTypeCode>::is_taped);
811
812
817 static constexpr bool is_real_valued =
818 (!boost::is_complex<ScalarType>::value);
819
820
825 static constexpr bool is_complex_valued =
826 !(NumberTraits<ScalarType, ADNumberTypeCode>::is_real_valued);
827
828
833 static constexpr unsigned int n_supported_derivative_levels =
834 internal::ADNumberInfoFromEnum<
835 typename internal::RemoveComplexWrapper<ScalarType>::type,
836 ADNumberTypeCode>::n_supported_derivative_levels;
837
838# endif
839
840
845 using scalar_type = ScalarType;
846
847
851 using real_type = typename internal::ADNumberInfoFromEnum<
852 typename internal::RemoveComplexWrapper<ScalarType>::type,
853 ADNumberTypeCode>::real_type;
854
855
859 using complex_type = std::complex<real_type>;
860
861
865 using ad_type =
866 typename std::conditional_t<is_real_valued, real_type, complex_type>;
867
871 using derivative_type = std::conditional_t<
872 is_real_valued,
873 typename internal::ADNumberInfoFromEnum<
874 typename internal::RemoveComplexWrapper<ScalarType>::type,
875 ADNumberTypeCode>::derivative_type,
876 std::complex<typename internal::ADNumberInfoFromEnum<
877 typename internal::RemoveComplexWrapper<ScalarType>::type,
878 ADNumberTypeCode>::derivative_type>>;
879
880
884 static scalar_type get_scalar_value(const ad_type &x)
885 {
886 // Some tricky conversion cases to consider here:
887 // - Nested AD numbers
888 // - std::complex<double> --> std::complex<float>
889 // e.g. when ScalarType = float and ADNumberTypeCode = adolc_taped
890 // Therefore, we use the internal casting mechanism
891 // provided by the internal::NumberType struct.
893 internal::ExtractData<ad_type>::value(x));
894 }
895
896
900 static derivative_type get_directional_derivative(
901 const ad_type &x, const unsigned int direction)
902 {
903 return internal::ExtractData<ad_type>::directional_derivative(
904 x, direction);
905 }
906
907
912 static unsigned int n_directional_derivatives(const ad_type &x)
913 {
914 return internal::ExtractData<ad_type>::n_directional_derivatives(x);
915 }
916
917
918 static_assert((is_real_valued == true ?
919 std::is_same_v<ad_type, real_type> :
920 std::is_same_v<ad_type, complex_type>),
921 "Incorrect template type selected for ad_type");
922
923 static_assert((is_complex_valued == true ?
924 boost::is_complex<scalar_type>::value :
925 true),
926 "Expected a complex float_type");
927
928 static_assert((is_complex_valued == true ?
929 boost::is_complex<ad_type>::value :
930 true),
931 "Expected a complex ad_type");
932 };
933
934# ifdef __clang__
935
936 template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
937 const bool NumberTraits<
938 ScalarType,
939 ADNumberTypeCode,
940 std::enable_if_t<
941 std::is_floating_point_v<ScalarType> ||
942 (boost::is_complex<ScalarType>::value &&
943 std::is_floating_point_v<typename internal::RemoveComplexWrapper<
944 ScalarType>::type>)>>::is_taped =
945 internal::ADNumberInfoFromEnum<
946 typename internal::RemoveComplexWrapper<ScalarType>::type,
947 ADNumberTypeCode>::is_taped;
948
949
950 template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
951 const bool NumberTraits<
952 ScalarType,
953 ADNumberTypeCode,
954 std::enable_if_t<
955 std::is_floating_point_v<ScalarType> ||
956 (boost::is_complex<ScalarType>::value &&
957 std::is_floating_point_v<typename internal::RemoveComplexWrapper<
958 ScalarType>::type>)>>::is_tapeless =
959 !(NumberTraits<ScalarType, ADNumberTypeCode>::is_taped);
960
961
962 template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
963 const bool NumberTraits<
964 ScalarType,
965 ADNumberTypeCode,
966 std::enable_if_t<
967 std::is_floating_point_v<ScalarType> ||
968 (boost::is_complex<ScalarType>::value &&
969 std::is_floating_point_v<typename internal::RemoveComplexWrapper<
970 ScalarType>::type>)>>::is_real_valued =
971 (!boost::is_complex<ScalarType>::value);
972
973
974 template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
975 const bool NumberTraits<
976 ScalarType,
977 ADNumberTypeCode,
978 std::enable_if_t<
979 std::is_floating_point_v<ScalarType> ||
980 (boost::is_complex<ScalarType>::value &&
981 std::is_floating_point_v<typename internal::RemoveComplexWrapper<
982 ScalarType>::type>)>>::is_complex_valued =
983 !(NumberTraits<ScalarType, ADNumberTypeCode>::is_real_valued);
984
985
986 template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
987 const unsigned int NumberTraits<
988 ScalarType,
989 ADNumberTypeCode,
990 std::enable_if_t<
991 std::is_floating_point_v<ScalarType> ||
992 (boost::is_complex<ScalarType>::value &&
993 std::is_floating_point_v<typename internal::RemoveComplexWrapper<
994 ScalarType>::type>)>>::n_supported_derivative_levels =
995 internal::ADNumberInfoFromEnum<
996 typename internal::RemoveComplexWrapper<ScalarType>::type,
997 ADNumberTypeCode>::n_supported_derivative_levels;
998
999# else
1000
1001 template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
1002 constexpr bool NumberTraits<
1003 ScalarType,
1004 ADNumberTypeCode,
1005 std::enable_if_t<
1006 std::is_floating_point_v<ScalarType> ||
1007 (boost::is_complex<ScalarType>::value &&
1008 std::is_floating_point_v<typename internal::RemoveComplexWrapper<
1009 ScalarType>::type>)>>::is_taped;
1010
1011
1012 template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
1013 constexpr bool NumberTraits<
1014 ScalarType,
1015 ADNumberTypeCode,
1016 std::enable_if_t<
1017 std::is_floating_point_v<ScalarType> ||
1018 (boost::is_complex<ScalarType>::value &&
1019 std::is_floating_point_v<typename internal::RemoveComplexWrapper<
1020 ScalarType>::type>)>>::is_tapeless;
1021
1022
1023 template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
1024 constexpr bool NumberTraits<
1025 ScalarType,
1026 ADNumberTypeCode,
1027 std::enable_if_t<
1028 std::is_floating_point_v<ScalarType> ||
1029 (boost::is_complex<ScalarType>::value &&
1030 std::is_floating_point_v<typename internal::RemoveComplexWrapper<
1031 ScalarType>::type>)>>::is_real_valued;
1032
1033
1034 template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
1035 constexpr bool NumberTraits<
1036 ScalarType,
1037 ADNumberTypeCode,
1038 std::enable_if_t<
1039 std::is_floating_point_v<ScalarType> ||
1040 (boost::is_complex<ScalarType>::value &&
1041 std::is_floating_point_v<typename internal::RemoveComplexWrapper<
1042 ScalarType>::type>)>>::is_complex_valued;
1043
1044
1045 template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
1046 constexpr unsigned int NumberTraits<
1047 ScalarType,
1048 ADNumberTypeCode,
1049 std::enable_if_t<
1050 std::is_floating_point_v<ScalarType> ||
1051 (boost::is_complex<ScalarType>::value &&
1052 std::is_floating_point_v<typename internal::RemoveComplexWrapper<
1053 ScalarType>::type>)>>::n_supported_derivative_levels;
1054
1055# endif
1056
1057
1058
1068 template <typename ScalarType>
1069 struct NumberTraits<
1070 ScalarType,
1072 std::enable_if_t<
1073 std::is_floating_point_v<ScalarType> ||
1074 (boost::is_complex<ScalarType>::value &&
1075 std::is_floating_point_v<
1076 typename internal::RemoveComplexWrapper<ScalarType>::type>)>>
1077 {
1081 static constexpr enum NumberTypes type_code = NumberTypes::none;
1082
1083 // The clang compiler does not seem to like these
1084 // variables being defined as constant expressions
1085 // (the tests <adolc|sacado>/ad_number_traits_02 will
1086 // fail with linking errors). However, GCC complains
1087 // about the use of non-constant expressions in
1088 // std::conditional.
1089# ifdef __clang__
1090
1095 static const bool is_taped;
1096
1097
1102 static const bool is_tapeless;
1103
1104
1109 static const bool is_real_valued;
1110
1111
1116 static const bool is_complex_valued;
1117
1118
1123 static const unsigned int n_supported_derivative_levels;
1124
1125# else
1126
1131 static constexpr bool is_taped = false;
1132
1133
1138 static constexpr bool is_tapeless = false;
1139
1140
1145 static constexpr bool is_real_valued =
1146 (!boost::is_complex<ScalarType>::value);
1147
1148
1153 static constexpr bool is_complex_valued = !is_real_valued;
1154
1155
1160 static constexpr unsigned int n_supported_derivative_levels = 0;
1161
1162# endif
1163
1164
1169 using scalar_type = ScalarType;
1170
1171
1175 using real_type =
1176 typename ::numbers::NumberTraits<scalar_type>::real_type;
1177
1178
1182 using complex_type = std::complex<real_type>;
1183
1184
1188 using ad_type = ScalarType;
1189
1193 using derivative_type = ScalarType;
1194
1195
1199 static scalar_type
1200 get_scalar_value(const ad_type &x)
1201 {
1202 return x;
1203 }
1204
1205
1209 static derivative_type
1210 get_directional_derivative(const ad_type &, const unsigned int)
1211 {
1212 Assert(
1213 false,
1214 ExcMessage(
1215 "Floating point/arithmetic numbers have no directional derivatives."));
1216 return derivative_type();
1217 }
1218
1219
1224 static unsigned int
1225 n_directional_derivatives(const ad_type &)
1226 {
1227 Assert(
1228 false,
1229 ExcMessage(
1230 "Floating point/arithmetic numbers have no directional derivatives."));
1231 return 0;
1232 }
1233 };
1234
1235# ifdef __clang__
1236
1237 template <typename ScalarType>
1238 const bool NumberTraits<
1239 ScalarType,
1241 std::enable_if_t<
1242 std::is_floating_point_v<ScalarType> ||
1243 (boost::is_complex<ScalarType>::value &&
1244 std::is_floating_point_v<typename internal::RemoveComplexWrapper<
1245 ScalarType>::type>)>>::is_taped = false;
1246
1247
1248 template <typename ScalarType>
1249 const bool NumberTraits<
1250 ScalarType,
1252 std::enable_if_t<
1253 std::is_floating_point_v<ScalarType> ||
1254 (boost::is_complex<ScalarType>::value &&
1255 std::is_floating_point_v<typename internal::RemoveComplexWrapper<
1256 ScalarType>::type>)>>::is_tapeless = false;
1257
1258
1259 template <typename ScalarType>
1260 const bool NumberTraits<
1261 ScalarType,
1263 std::enable_if_t<
1264 std::is_floating_point_v<ScalarType> ||
1265 (boost::is_complex<ScalarType>::value &&
1266 std::is_floating_point_v<typename internal::RemoveComplexWrapper<
1267 ScalarType>::type>)>>::is_real_valued =
1268 (!boost::is_complex<ScalarType>::value);
1269
1270
1271 template <typename ScalarType>
1272 const bool NumberTraits<
1273 ScalarType,
1275 std::enable_if_t<
1276 std::is_floating_point_v<ScalarType> ||
1277 (boost::is_complex<ScalarType>::value &&
1278 std::is_floating_point_v<typename internal::RemoveComplexWrapper<
1279 ScalarType>::type>)>>::is_complex_valued =
1280 !(NumberTraits<ScalarType, NumberTypes::none>::is_real_valued);
1281
1282
1283 template <typename ScalarType>
1284 const unsigned int NumberTraits<
1285 ScalarType,
1287 std::enable_if_t<
1288 std::is_floating_point_v<ScalarType> ||
1289 (boost::is_complex<ScalarType>::value &&
1290 std::is_floating_point_v<typename internal::RemoveComplexWrapper<
1291 ScalarType>::type>)>>::n_supported_derivative_levels = 0;
1292
1293# else
1294
1295 template <typename ScalarType>
1296 constexpr bool NumberTraits<
1297 ScalarType,
1299 std::enable_if_t<
1300 std::is_floating_point_v<ScalarType> ||
1301 (boost::is_complex<ScalarType>::value &&
1302 std::is_floating_point_v<typename internal::RemoveComplexWrapper<
1303 ScalarType>::type>)>>::is_taped;
1304
1305
1306 template <typename ScalarType>
1307 constexpr bool NumberTraits<
1308 ScalarType,
1310 std::enable_if_t<
1311 std::is_floating_point_v<ScalarType> ||
1312 (boost::is_complex<ScalarType>::value &&
1313 std::is_floating_point_v<typename internal::RemoveComplexWrapper<
1314 ScalarType>::type>)>>::is_tapeless;
1315
1316
1317 template <typename ScalarType>
1318 constexpr bool NumberTraits<
1319 ScalarType,
1321 std::enable_if_t<
1322 std::is_floating_point_v<ScalarType> ||
1323 (boost::is_complex<ScalarType>::value &&
1324 std::is_floating_point_v<typename internal::RemoveComplexWrapper<
1325 ScalarType>::type>)>>::is_real_valued;
1326
1327
1328 template <typename ScalarType>
1329 constexpr bool NumberTraits<
1330 ScalarType,
1332 std::enable_if_t<
1333 std::is_floating_point_v<ScalarType> ||
1334 (boost::is_complex<ScalarType>::value &&
1335 std::is_floating_point_v<typename internal::RemoveComplexWrapper<
1336 ScalarType>::type>)>>::is_complex_valued;
1337
1338
1339 template <typename ScalarType>
1340 constexpr unsigned int NumberTraits<
1341 ScalarType,
1343 std::enable_if_t<
1344 std::is_floating_point_v<ScalarType> ||
1345 (boost::is_complex<ScalarType>::value &&
1346 std::is_floating_point_v<typename internal::RemoveComplexWrapper<
1347 ScalarType>::type>)>>::n_supported_derivative_levels;
1348
1349# endif
1350
1351
1370 template <typename ScalarType>
1371 struct ADNumberTraits<
1372 ScalarType,
1373 std::enable_if_t<std::is_floating_point_v<ScalarType>>>
1374 : NumberTraits<ScalarType, NumberTypes::none>
1375 {};
1376
1380 template <typename ComplexScalarType>
1381 struct ADNumberTraits<
1382 ComplexScalarType,
1383 std::enable_if_t<
1384 boost::is_complex<ComplexScalarType>::value &&
1385 std::is_floating_point_v<typename ComplexScalarType::value_type>>>
1386 : NumberTraits<ComplexScalarType, NumberTypes::none>
1387 {};
1388
1389 } // namespace AD
1390} // namespace Differentiation
1391
1392#endif // DOXYGEN
1393
1395
1396#endif
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:498
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:499
#define Assert(cond, exc)
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
STL namespace.
static constexpr DEAL_II_HOST_DEVICE_ALWAYS_INLINE const T & value(const T &t)
Definition numbers.h:697