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
ad_number_traits.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 - 2024 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_ad_number_traits_h
14#define dealii_differentiation_ad_ad_number_traits_h
15
16#include <deal.II/base/config.h>
17
20
22
23#include <boost/type_traits.hpp>
24
25#include <complex>
26#include <type_traits>
27
29
30namespace Differentiation
31{
32 namespace AD
33 {
45 template <typename ScalarType,
46 enum NumberTypes ADNumberTypeCode,
47 typename T = void>
49
50
51
64 template <typename ADNumberType, typename T = void>
66
67
72 namespace internal
73 {
74 // The following three classes, namely ADNumberInfoFromEnum, Marking, and
75 // ExtractData, are those that need to be implemented for each new
76 // auto-differentiable number type. This information is then used by
77 // NumberTraits and ADNumberTraits to provide a uniform interface, as used
78 // by our drivers, to the underlying number types.
79
80
104 template <typename ScalarType,
105 enum NumberTypes ADNumberTypeCode,
106 typename = void>
108
109
139 template <typename ADNumberType, typename T = void>
140 struct Marking;
141
142
172 template <typename ADNumberType, typename T = void>
174
175
188 template <typename ADNumberTrait, typename T = void>
190
191
206 template <typename T>
207 struct NumberType;
208
209
214 template <typename Number>
216
217 } // namespace internal
218
219
226 template <typename NumberType>
227 struct is_ad_number;
228
229
236 template <typename NumberType, typename = void>
238
239
246 template <typename NumberType, typename = void>
248
249
256 template <typename NumberType, typename = void>
258
259
266 template <typename NumberType, typename = void>
268
269 } // namespace AD
270} // namespace Differentiation
271
272
273/* ----------- inline and template functions and specializations ----------- */
274
275
276#ifndef DOXYGEN
277
278
279namespace Differentiation
280{
281 namespace AD
282 {
283 namespace internal
284 {
285 template <typename ADNumberTrait, typename>
286 struct HasRequiredADInfo : std::false_type
287 {};
288
289
301 template <typename ADNumberTrait>
302 struct HasRequiredADInfo<
303 ADNumberTrait,
304 decltype((void)ADNumberTrait::type_code,
305 (void)ADNumberTrait::is_taped,
306 (void)std::declval<typename ADNumberTrait::real_type>(),
307 (void)std::declval<typename ADNumberTrait::derivative_type>(),
308 void())>
309 : std::conditional_t<
310 std::is_floating_point_v<typename ADNumberTrait::real_type>,
311 std::false_type,
312 std::true_type>
313 {};
314
315
320 template <typename ScalarType>
321 struct ADNumberInfoFromEnum<
322 ScalarType,
324 std::enable_if_t<std::is_floating_point_v<ScalarType>>>
325 {
326 static const bool is_taped = false;
327 using real_type = ScalarType;
328 using derivative_type = ScalarType;
329 static const unsigned int n_supported_derivative_levels = 0;
330 };
331
332
338 template <typename ScalarType>
339 struct Marking<ScalarType,
340 std::enable_if_t<std::is_floating_point_v<ScalarType>>>
341 {
349 template <typename ADNumberType>
350 static void
351 independent_variable(const ScalarType &in,
352 const unsigned int,
353 const unsigned int,
354 ADNumberType &out)
355 {
356 out = in;
357 }
358
359 /*
360 * Initialize the state of a dependent variable.
361 */
362 template <typename ADNumberType>
363 static void
364 dependent_variable(ADNumberType &, const ScalarType &)
365 {
367 false,
369 "Floating point numbers cannot be marked as dependent variables."));
370 }
371 };
372
373
377 template <typename ADNumberType>
378 struct Marking<ADNumberType,
379 std::enable_if_t<boost::is_complex<ADNumberType>::value>>
380 {
381 /*
382 * Initialize the state of an independent variable.
383 */
384 template <typename ScalarType>
385 static void
386 independent_variable(const ScalarType &in,
387 const unsigned int,
388 const unsigned int,
389 ADNumberType &out)
390 {
392 false,
394 "Marking for complex numbers has not yet been implemented."));
395 out = in;
396 }
397
398 /*
399 * Initialize the state of a dependent variable.
400 */
401 template <typename ScalarType>
402 static void
403 dependent_variable(ADNumberType &, const ScalarType &)
404 {
406 false,
408 "Marking for complex numbers has not yet been implemented."));
409 }
410 };
411
412 } // namespace internal
413
414
415 template <typename NumberType, typename>
416 struct is_taped_ad_number : std::false_type
417 {};
418
419
420 template <typename NumberType, typename>
421 struct is_tapeless_ad_number : std::false_type
422 {};
423
424
425 template <typename NumberType, typename>
426 struct is_real_valued_ad_number : std::false_type
427 {};
428
429
430 template <typename NumberType, typename>
431 struct is_complex_valued_ad_number : std::false_type
432 {};
433
434
440 template <typename NumberType>
441 struct is_ad_number
442 : internal::HasRequiredADInfo<ADNumberTraits<std::decay_t<NumberType>>>
443 {};
444
445
450 template <typename NumberType>
451 struct is_taped_ad_number<
452 NumberType,
453 std::enable_if_t<ADNumberTraits<std::decay_t<NumberType>>::is_taped>>
454 : std::true_type
455 {};
456
457
462 template <typename NumberType>
463 struct is_tapeless_ad_number<
464 NumberType,
465 std::enable_if_t<ADNumberTraits<std::decay_t<NumberType>>::is_tapeless>>
466 : std::true_type
467 {};
468
469
475 template <typename NumberType>
476 struct is_real_valued_ad_number<
477 NumberType,
478 std::enable_if_t<
479 ADNumberTraits<std::decay_t<NumberType>>::is_real_valued>>
480 : std::true_type
481 {};
482
483
489 template <typename NumberType>
490 struct is_complex_valued_ad_number<
491 NumberType,
492 std::enable_if_t<
493 ADNumberTraits<std::decay_t<NumberType>>::is_complex_valued>>
494 : std::true_type
495 {};
496
497
498 namespace internal
499 {
504 template <typename Number>
505 struct RemoveComplexWrapper
506 {
507 using type = Number;
508 };
509
510
516 template <typename Number>
517 struct RemoveComplexWrapper<std::complex<Number>>
518 {
519 using type = typename RemoveComplexWrapper<Number>::type;
520 };
521
522
528 template <typename NumberType>
529 struct ExtractData<NumberType,
530 std::enable_if_t<std::is_floating_point_v<NumberType>>>
531 {
535 static const NumberType &
536 value(const NumberType &x)
537 {
538 return x;
539 }
540
541
545 static unsigned int
546 n_directional_derivatives(const NumberType &)
547 {
548 return 0;
549 }
550
551
555 static NumberType
556 directional_derivative(const NumberType &, const unsigned int)
557 {
558 return 0.0;
559 }
560 };
561
562
563
568 template <typename ADNumberType>
569 struct ExtractData<std::complex<ADNumberType>>
570 {
572 "Expected an auto-differentiable number.");
573
574
578 static std::complex<typename ADNumberTraits<ADNumberType>::scalar_type>
579 value(const std::complex<ADNumberType> &x)
580 {
581 return std::complex<
582 typename ADNumberTraits<ADNumberType>::scalar_type>(
583 ExtractData<ADNumberType>::value(x.real()),
584 ExtractData<ADNumberType>::value(x.imag()));
585 }
586
587
591 static unsigned int
592 n_directional_derivatives(const std::complex<ADNumberType> &x)
593 {
594 return ExtractData<ADNumberType>::n_directional_derivatives(x.real());
595 }
596
597
601 static std::complex<
602 typename ADNumberTraits<ADNumberType>::derivative_type>
603 directional_derivative(const std::complex<ADNumberType> &x,
604 const unsigned int direction)
605 {
606 return std::complex<
607 typename ADNumberTraits<ADNumberType>::derivative_type>(
608 ExtractData<ADNumberType>::directional_derivative(x.real(),
609 direction),
610 ExtractData<ADNumberType>::directional_derivative(x.imag(),
611 direction));
612 }
613 };
614
615
616 template <typename T>
617 struct NumberType
618 {
622 template <typename F>
623 static auto
624 value(const F &f, std::enable_if_t<!is_ad_number<F>::value> * = nullptr)
626 {
627 // We call the other function defined in the numbers
628 // header to take care of all of the usual cases.
629 return ::internal::NumberType<T>::value(f);
630 }
631
638 template <typename F>
639 static T
640 value(const F &f,
641 std::enable_if_t<is_ad_number<F>::value &&
642 std::is_floating_point_v<T>> * = nullptr)
643 {
644 // We recursively call this function in case the AD number is a
645 // nested one. The recursion ends when the extracted value is
646 // a floating point number.
647 return NumberType<T>::value(ExtractData<F>::value(f));
648 }
649
656 template <typename F>
657 static T
658 value(const F &f,
659 std::enable_if_t<is_ad_number<F>::value && is_ad_number<T>::value>
660 * = nullptr)
661 {
662 return T(f);
663 }
664 };
665
666 template <typename T>
667 struct NumberType<std::complex<T>>
668 {
672 template <typename F>
673 static auto
674 value(const F &f, std::enable_if_t<!is_ad_number<F>::value> * = nullptr)
675 -> decltype(::internal::NumberType<std::complex<T>>::value(f))
676 {
677 // We call the other function defined in the numbers
678 // header to take care of all of the usual cases.
679 return ::internal::NumberType<std::complex<T>>::value(f);
680 }
681
682
687 template <typename F>
688 static std::complex<T>
689 value(const F &f,
690 std::enable_if_t<is_ad_number<F>::value &&
691 std::is_floating_point_v<T>> * = nullptr)
692 {
693 // We recursively call this function in case the AD number is a
694 // nested one. The recursion ends when the extracted value is
695 // a floating point number.
696 return std::complex<T>(
697 NumberType<T>::value(ExtractData<F>::value(f)));
698 }
699
700 template <typename F>
701 static std::complex<T>
702 value(const std::complex<F> &f)
703 {
704 // Deal with the two parts of the input complex
705 // number individually.
706 return std::complex<T>(NumberType<T>::value(f.real()),
707 NumberType<T>::value(f.imag()));
708 }
709 };
710
711 } // namespace internal
712
713
714
735 template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
736 struct NumberTraits<
737 ScalarType,
738 ADNumberTypeCode,
739 std::enable_if_t<
740 std::is_floating_point_v<ScalarType> ||
741 (boost::is_complex<ScalarType>::value &&
742 std::is_floating_point_v<
743 typename internal::RemoveComplexWrapper<ScalarType>::type>)>>
744 {
748 static constexpr enum NumberTypes type_code = ADNumberTypeCode;
749
750 // The clang compiler does not seem to like these
751 // variables being defined as constant expressions
752 // (the tests <adolc|sacado>/ad_number_traits_02 will
753 // fail with linking errors). However, GCC complains
754 // about the use of non-constant expressions in
755 // std::conditional.
756# ifdef __clang__
757
762 static const bool is_taped;
763
764
769 static const bool is_tapeless;
770
771
776 static const bool is_real_valued;
777
778
783 static const bool is_complex_valued;
784
785
790 static const unsigned int n_supported_derivative_levels;
791
792# else
793
798 static constexpr bool is_taped = internal::ADNumberInfoFromEnum<
799 typename internal::RemoveComplexWrapper<ScalarType>::type,
800 ADNumberTypeCode>::is_taped;
801
802
807 static constexpr bool is_tapeless =
808 !(NumberTraits<ScalarType, ADNumberTypeCode>::is_taped);
809
810
815 static constexpr bool is_real_valued =
816 (!boost::is_complex<ScalarType>::value);
817
818
823 static constexpr bool is_complex_valued =
824 !(NumberTraits<ScalarType, ADNumberTypeCode>::is_real_valued);
825
826
831 static constexpr unsigned int n_supported_derivative_levels =
832 internal::ADNumberInfoFromEnum<
833 typename internal::RemoveComplexWrapper<ScalarType>::type,
834 ADNumberTypeCode>::n_supported_derivative_levels;
835
836# endif
837
838
843 using scalar_type = ScalarType;
844
845
849 using real_type = typename internal::ADNumberInfoFromEnum<
850 typename internal::RemoveComplexWrapper<ScalarType>::type,
851 ADNumberTypeCode>::real_type;
852
853
857 using complex_type = std::complex<real_type>;
858
859
863 using ad_type =
864 typename std::conditional_t<is_real_valued, real_type, complex_type>;
865
869 using derivative_type = std::conditional_t<
870 is_real_valued,
871 typename internal::ADNumberInfoFromEnum<
872 typename internal::RemoveComplexWrapper<ScalarType>::type,
873 ADNumberTypeCode>::derivative_type,
874 std::complex<typename internal::ADNumberInfoFromEnum<
875 typename internal::RemoveComplexWrapper<ScalarType>::type,
876 ADNumberTypeCode>::derivative_type>>;
877
878
882 static scalar_type get_scalar_value(const ad_type &x)
883 {
884 // Some tricky conversion cases to consider here:
885 // - Nested AD numbers
886 // - std::complex<double> --> std::complex<float>
887 // e.g. when ScalarType = float and ADNumberTypeCode = adolc_taped
888 // Therefore, we use the internal casting mechanism
889 // provided by the internal::NumberType struct.
891 internal::ExtractData<ad_type>::value(x));
892 }
893
894
898 static derivative_type get_directional_derivative(
899 const ad_type &x, const unsigned int direction)
900 {
901 return internal::ExtractData<ad_type>::directional_derivative(
902 x, direction);
903 }
904
905
910 static unsigned int n_directional_derivatives(const ad_type &x)
911 {
912 return internal::ExtractData<ad_type>::n_directional_derivatives(x);
913 }
914
915
916 static_assert((is_real_valued == true ?
917 std::is_same_v<ad_type, real_type> :
918 std::is_same_v<ad_type, complex_type>),
919 "Incorrect template type selected for ad_type");
920
921 static_assert((is_complex_valued == true ?
922 boost::is_complex<scalar_type>::value :
923 true),
924 "Expected a complex float_type");
925
926 static_assert((is_complex_valued == true ?
927 boost::is_complex<ad_type>::value :
928 true),
929 "Expected a complex ad_type");
930 };
931
932# ifdef __clang__
933
934 template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
935 const bool NumberTraits<
936 ScalarType,
937 ADNumberTypeCode,
938 std::enable_if_t<
939 std::is_floating_point_v<ScalarType> ||
940 (boost::is_complex<ScalarType>::value &&
941 std::is_floating_point_v<typename internal::RemoveComplexWrapper<
942 ScalarType>::type>)>>::is_taped =
943 internal::ADNumberInfoFromEnum<
944 typename internal::RemoveComplexWrapper<ScalarType>::type,
945 ADNumberTypeCode>::is_taped;
946
947
948 template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
949 const bool NumberTraits<
950 ScalarType,
951 ADNumberTypeCode,
952 std::enable_if_t<
953 std::is_floating_point_v<ScalarType> ||
954 (boost::is_complex<ScalarType>::value &&
955 std::is_floating_point_v<typename internal::RemoveComplexWrapper<
956 ScalarType>::type>)>>::is_tapeless =
957 !(NumberTraits<ScalarType, ADNumberTypeCode>::is_taped);
958
959
960 template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
961 const bool NumberTraits<
962 ScalarType,
963 ADNumberTypeCode,
964 std::enable_if_t<
965 std::is_floating_point_v<ScalarType> ||
966 (boost::is_complex<ScalarType>::value &&
967 std::is_floating_point_v<typename internal::RemoveComplexWrapper<
968 ScalarType>::type>)>>::is_real_valued =
969 (!boost::is_complex<ScalarType>::value);
970
971
972 template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
973 const bool NumberTraits<
974 ScalarType,
975 ADNumberTypeCode,
976 std::enable_if_t<
977 std::is_floating_point_v<ScalarType> ||
978 (boost::is_complex<ScalarType>::value &&
979 std::is_floating_point_v<typename internal::RemoveComplexWrapper<
980 ScalarType>::type>)>>::is_complex_valued =
981 !(NumberTraits<ScalarType, ADNumberTypeCode>::is_real_valued);
982
983
984 template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
985 const unsigned int NumberTraits<
986 ScalarType,
987 ADNumberTypeCode,
988 std::enable_if_t<
989 std::is_floating_point_v<ScalarType> ||
990 (boost::is_complex<ScalarType>::value &&
991 std::is_floating_point_v<typename internal::RemoveComplexWrapper<
992 ScalarType>::type>)>>::n_supported_derivative_levels =
993 internal::ADNumberInfoFromEnum<
994 typename internal::RemoveComplexWrapper<ScalarType>::type,
995 ADNumberTypeCode>::n_supported_derivative_levels;
996
997# else
998
999 template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
1000 constexpr bool NumberTraits<
1001 ScalarType,
1002 ADNumberTypeCode,
1003 std::enable_if_t<
1004 std::is_floating_point_v<ScalarType> ||
1005 (boost::is_complex<ScalarType>::value &&
1006 std::is_floating_point_v<typename internal::RemoveComplexWrapper<
1007 ScalarType>::type>)>>::is_taped;
1008
1009
1010 template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
1011 constexpr bool NumberTraits<
1012 ScalarType,
1013 ADNumberTypeCode,
1014 std::enable_if_t<
1015 std::is_floating_point_v<ScalarType> ||
1016 (boost::is_complex<ScalarType>::value &&
1017 std::is_floating_point_v<typename internal::RemoveComplexWrapper<
1018 ScalarType>::type>)>>::is_tapeless;
1019
1020
1021 template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
1022 constexpr bool NumberTraits<
1023 ScalarType,
1024 ADNumberTypeCode,
1025 std::enable_if_t<
1026 std::is_floating_point_v<ScalarType> ||
1027 (boost::is_complex<ScalarType>::value &&
1028 std::is_floating_point_v<typename internal::RemoveComplexWrapper<
1029 ScalarType>::type>)>>::is_real_valued;
1030
1031
1032 template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
1033 constexpr bool NumberTraits<
1034 ScalarType,
1035 ADNumberTypeCode,
1036 std::enable_if_t<
1037 std::is_floating_point_v<ScalarType> ||
1038 (boost::is_complex<ScalarType>::value &&
1039 std::is_floating_point_v<typename internal::RemoveComplexWrapper<
1040 ScalarType>::type>)>>::is_complex_valued;
1041
1042
1043 template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
1044 constexpr unsigned int NumberTraits<
1045 ScalarType,
1046 ADNumberTypeCode,
1047 std::enable_if_t<
1048 std::is_floating_point_v<ScalarType> ||
1049 (boost::is_complex<ScalarType>::value &&
1050 std::is_floating_point_v<typename internal::RemoveComplexWrapper<
1051 ScalarType>::type>)>>::n_supported_derivative_levels;
1052
1053# endif
1054
1055
1056
1066 template <typename ScalarType>
1067 struct NumberTraits<
1068 ScalarType,
1070 std::enable_if_t<
1071 std::is_floating_point_v<ScalarType> ||
1072 (boost::is_complex<ScalarType>::value &&
1073 std::is_floating_point_v<
1074 typename internal::RemoveComplexWrapper<ScalarType>::type>)>>
1075 {
1079 static constexpr enum NumberTypes type_code = NumberTypes::none;
1080
1081 // The clang compiler does not seem to like these
1082 // variables being defined as constant expressions
1083 // (the tests <adolc|sacado>/ad_number_traits_02 will
1084 // fail with linking errors). However, GCC complains
1085 // about the use of non-constant expressions in
1086 // std::conditional.
1087# ifdef __clang__
1088
1093 static const bool is_taped;
1094
1095
1100 static const bool is_tapeless;
1101
1102
1107 static const bool is_real_valued;
1108
1109
1114 static const bool is_complex_valued;
1115
1116
1121 static const unsigned int n_supported_derivative_levels;
1122
1123# else
1124
1129 static constexpr bool is_taped = false;
1130
1131
1136 static constexpr bool is_tapeless = false;
1137
1138
1143 static constexpr bool is_real_valued =
1144 (!boost::is_complex<ScalarType>::value);
1145
1146
1151 static constexpr bool is_complex_valued = !is_real_valued;
1152
1153
1158 static constexpr unsigned int n_supported_derivative_levels = 0;
1159
1160# endif
1161
1162
1167 using scalar_type = ScalarType;
1168
1169
1173 using real_type =
1174 typename ::numbers::NumberTraits<scalar_type>::real_type;
1175
1176
1180 using complex_type = std::complex<real_type>;
1181
1182
1186 using ad_type = ScalarType;
1187
1191 using derivative_type = ScalarType;
1192
1193
1197 static scalar_type
1198 get_scalar_value(const ad_type &x)
1199 {
1200 return x;
1201 }
1202
1203
1207 static derivative_type
1208 get_directional_derivative(const ad_type &, const unsigned int)
1209 {
1210 Assert(
1211 false,
1212 ExcMessage(
1213 "Floating point/arithmetic numbers have no directional derivatives."));
1214 return derivative_type();
1215 }
1216
1217
1222 static unsigned int
1223 n_directional_derivatives(const ad_type &)
1224 {
1225 Assert(
1226 false,
1227 ExcMessage(
1228 "Floating point/arithmetic numbers have no directional derivatives."));
1229 return 0;
1230 }
1231 };
1232
1233# ifdef __clang__
1234
1235 template <typename ScalarType>
1236 const bool NumberTraits<
1237 ScalarType,
1239 std::enable_if_t<
1240 std::is_floating_point_v<ScalarType> ||
1241 (boost::is_complex<ScalarType>::value &&
1242 std::is_floating_point_v<typename internal::RemoveComplexWrapper<
1243 ScalarType>::type>)>>::is_taped = false;
1244
1245
1246 template <typename ScalarType>
1247 const bool NumberTraits<
1248 ScalarType,
1250 std::enable_if_t<
1251 std::is_floating_point_v<ScalarType> ||
1252 (boost::is_complex<ScalarType>::value &&
1253 std::is_floating_point_v<typename internal::RemoveComplexWrapper<
1254 ScalarType>::type>)>>::is_tapeless = false;
1255
1256
1257 template <typename ScalarType>
1258 const bool NumberTraits<
1259 ScalarType,
1261 std::enable_if_t<
1262 std::is_floating_point_v<ScalarType> ||
1263 (boost::is_complex<ScalarType>::value &&
1264 std::is_floating_point_v<typename internal::RemoveComplexWrapper<
1265 ScalarType>::type>)>>::is_real_valued =
1266 (!boost::is_complex<ScalarType>::value);
1267
1268
1269 template <typename ScalarType>
1270 const bool NumberTraits<
1271 ScalarType,
1273 std::enable_if_t<
1274 std::is_floating_point_v<ScalarType> ||
1275 (boost::is_complex<ScalarType>::value &&
1276 std::is_floating_point_v<typename internal::RemoveComplexWrapper<
1277 ScalarType>::type>)>>::is_complex_valued =
1278 !(NumberTraits<ScalarType, NumberTypes::none>::is_real_valued);
1279
1280
1281 template <typename ScalarType>
1282 const unsigned int NumberTraits<
1283 ScalarType,
1285 std::enable_if_t<
1286 std::is_floating_point_v<ScalarType> ||
1287 (boost::is_complex<ScalarType>::value &&
1288 std::is_floating_point_v<typename internal::RemoveComplexWrapper<
1289 ScalarType>::type>)>>::n_supported_derivative_levels = 0;
1290
1291# else
1292
1293 template <typename ScalarType>
1294 constexpr bool NumberTraits<
1295 ScalarType,
1297 std::enable_if_t<
1298 std::is_floating_point_v<ScalarType> ||
1299 (boost::is_complex<ScalarType>::value &&
1300 std::is_floating_point_v<typename internal::RemoveComplexWrapper<
1301 ScalarType>::type>)>>::is_taped;
1302
1303
1304 template <typename ScalarType>
1305 constexpr bool NumberTraits<
1306 ScalarType,
1308 std::enable_if_t<
1309 std::is_floating_point_v<ScalarType> ||
1310 (boost::is_complex<ScalarType>::value &&
1311 std::is_floating_point_v<typename internal::RemoveComplexWrapper<
1312 ScalarType>::type>)>>::is_tapeless;
1313
1314
1315 template <typename ScalarType>
1316 constexpr bool NumberTraits<
1317 ScalarType,
1319 std::enable_if_t<
1320 std::is_floating_point_v<ScalarType> ||
1321 (boost::is_complex<ScalarType>::value &&
1322 std::is_floating_point_v<typename internal::RemoveComplexWrapper<
1323 ScalarType>::type>)>>::is_real_valued;
1324
1325
1326 template <typename ScalarType>
1327 constexpr bool NumberTraits<
1328 ScalarType,
1330 std::enable_if_t<
1331 std::is_floating_point_v<ScalarType> ||
1332 (boost::is_complex<ScalarType>::value &&
1333 std::is_floating_point_v<typename internal::RemoveComplexWrapper<
1334 ScalarType>::type>)>>::is_complex_valued;
1335
1336
1337 template <typename ScalarType>
1338 constexpr unsigned int NumberTraits<
1339 ScalarType,
1341 std::enable_if_t<
1342 std::is_floating_point_v<ScalarType> ||
1343 (boost::is_complex<ScalarType>::value &&
1344 std::is_floating_point_v<typename internal::RemoveComplexWrapper<
1345 ScalarType>::type>)>>::n_supported_derivative_levels;
1346
1347# endif
1348
1349
1368 template <typename ScalarType>
1369 struct ADNumberTraits<
1370 ScalarType,
1371 std::enable_if_t<std::is_floating_point_v<ScalarType>>>
1372 : NumberTraits<ScalarType, NumberTypes::none>
1373 {};
1374
1378 template <typename ComplexScalarType>
1379 struct ADNumberTraits<
1380 ComplexScalarType,
1381 std::enable_if_t<
1382 boost::is_complex<ComplexScalarType>::value &&
1383 std::is_floating_point_v<typename ComplexScalarType::value_type>>>
1384 : NumberTraits<ComplexScalarType, NumberTypes::none>
1385 {};
1386
1387 } // namespace AD
1388} // namespace Differentiation
1389
1390#endif // DOXYGEN
1391
1393
1394#endif
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
#define Assert(cond, exc)
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
constexpr char T
*  *  *  RotationFunction< dim, Number >::RotationFunction Number(dim)
STL namespace.
static constexpr const T & value(const T &t)
Definition numbers.h:662