Reference documentation for deal.II version 9.5.0
\(\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// Copyright (C) 2016 - 2023 by the deal.II authors
4//
5// This file is part of the deal.II library.
6//
7// The deal.II library is free software; you can use it, redistribute
8// it, and/or modify it under the terms of the GNU Lesser General
9// Public License as published by the Free Software Foundation; either
10// version 2.1 of the License, or (at your option) any later version.
11// The full text of the license can be found in the file LICENSE.md at
12// the top level directory of deal.II.
13//
14// ---------------------------------------------------------------------
15
16#ifndef dealii_differentiation_ad_ad_number_traits_h
17#define dealii_differentiation_ad_ad_number_traits_h
18
19#include <deal.II/base/config.h>
20
23
25
26#include <boost/type_traits.hpp>
27
28#include <complex>
29#include <type_traits>
30
32
33namespace Differentiation
34{
35 namespace AD
36 {
48 template <typename ScalarType,
49 enum NumberTypes ADNumberTypeCode,
50 typename T = void>
52
53
54
67 template <typename ADNumberType, typename T = void>
69
70
75 namespace internal
76 {
77 // The following three classes, namely ADNumberInfoFromEnum, Marking, and
78 // ExtractData, are those that need to be implemented for each new
79 // auto-differentiable number type. This information is then used by
80 // NumberTraits and ADNumberTraits to provide a uniform interface, as used
81 // by our drivers, to the underlying number types.
82
83
107 template <typename ScalarType,
108 enum NumberTypes ADNumberTypeCode,
109 typename = void>
111
112
142 template <typename ADNumberType, typename T = void>
143 struct Marking;
144
145
175 template <typename ADNumberType, typename T = void>
177
178
191 template <typename ADNumberTrait, typename T = void>
193
194
209 template <typename T>
210 struct NumberType;
211
212
217 template <typename Number>
219
220 } // namespace internal
221
222
229 template <typename NumberType>
230 struct is_ad_number;
231
232
239 template <typename NumberType, typename = void>
241
242
249 template <typename NumberType, typename = void>
251
252
259 template <typename NumberType, typename = void>
261
262
269 template <typename NumberType, typename = void>
271
272 } // namespace AD
273} // namespace Differentiation
274
275
276/* ----------- inline and template functions and specializations ----------- */
277
278
279#ifndef DOXYGEN
280
281
282namespace Differentiation
283{
284 namespace AD
285 {
286 namespace internal
287 {
288 template <typename ADNumberTrait, typename>
289 struct HasRequiredADInfo : std::false_type
290 {};
291
292
304 template <typename ADNumberTrait>
305 struct HasRequiredADInfo<
306 ADNumberTrait,
307 decltype((void)ADNumberTrait::type_code,
308 (void)ADNumberTrait::is_taped,
309 (void)std::declval<typename ADNumberTrait::real_type>(),
310 (void)std::declval<typename ADNumberTrait::derivative_type>(),
311 void())>
312 : std::conditional<
313 std::is_floating_point<typename ADNumberTrait::real_type>::value,
314 std::false_type,
315 std::true_type>::type
316 {};
317
318
323 template <typename ScalarType>
324 struct ADNumberInfoFromEnum<
325 ScalarType,
327 std::enable_if_t<std::is_floating_point<ScalarType>::value>>
328 {
329 static const bool is_taped = false;
330 using real_type = ScalarType;
331 using derivative_type = ScalarType;
332 static const unsigned int n_supported_derivative_levels = 0;
333 };
334
335
341 template <typename ScalarType>
342 struct Marking<
343 ScalarType,
344 std::enable_if_t<std::is_floating_point<ScalarType>::value>>
345 {
353 template <typename ADNumberType>
354 static void
355 independent_variable(const ScalarType &in,
356 const unsigned int,
357 const unsigned int,
358 ADNumberType &out)
359 {
360 out = in;
361 }
362
363 /*
364 * Initialize the state of a dependent variable.
365 */
366 template <typename ADNumberType>
367 static void
368 dependent_variable(ADNumberType &, const ScalarType &)
369 {
371 false,
373 "Floating point numbers cannot be marked as dependent variables."));
374 }
375 };
376
377
381 template <typename ADNumberType>
382 struct Marking<ADNumberType,
383 std::enable_if_t<boost::is_complex<ADNumberType>::value>>
384 {
385 /*
386 * Initialize the state of an independent variable.
387 */
388 template <typename ScalarType>
389 static void
390 independent_variable(const ScalarType &in,
391 const unsigned int,
392 const unsigned int,
393 ADNumberType &out)
394 {
396 false,
398 "Marking for complex numbers has not yet been implemented."));
399 out = in;
400 }
401
402 /*
403 * Initialize the state of a dependent variable.
404 */
405 template <typename ScalarType>
406 static void
407 dependent_variable(ADNumberType &, const ScalarType &)
408 {
410 false,
412 "Marking for complex numbers has not yet been implemented."));
413 }
414 };
415
416 } // namespace internal
417
418
419 template <typename NumberType, typename>
420 struct is_taped_ad_number : std::false_type
421 {};
422
423
424 template <typename NumberType, typename>
425 struct is_tapeless_ad_number : std::false_type
426 {};
427
428
429 template <typename NumberType, typename>
430 struct is_real_valued_ad_number : std::false_type
431 {};
432
433
434 template <typename NumberType, typename>
435 struct is_complex_valued_ad_number : std::false_type
436 {};
437
438
444 template <typename NumberType>
445 struct is_ad_number
446 : internal::HasRequiredADInfo<
447 ADNumberTraits<typename std::decay<NumberType>::type>>
448 {};
449
450
455 template <typename NumberType>
456 struct is_taped_ad_number<
457 NumberType,
458 std::enable_if_t<
459 ADNumberTraits<typename std::decay<NumberType>::type>::is_taped>>
460 : std::true_type
461 {};
462
463
468 template <typename NumberType>
469 struct is_tapeless_ad_number<
470 NumberType,
471 std::enable_if_t<
472 ADNumberTraits<typename std::decay<NumberType>::type>::is_tapeless>>
473 : std::true_type
474 {};
475
476
482 template <typename NumberType>
483 struct is_real_valued_ad_number<
484 NumberType,
485 std::enable_if_t<
486 ADNumberTraits<typename std::decay<NumberType>::type>::is_real_valued>>
487 : std::true_type
488 {};
489
490
496 template <typename NumberType>
497 struct is_complex_valued_ad_number<
498 NumberType,
499 std::enable_if_t<ADNumberTraits<
500 typename std::decay<NumberType>::type>::is_complex_valued>>
501 : std::true_type
502 {};
503
504
505 namespace internal
506 {
511 template <typename Number>
512 struct RemoveComplexWrapper
513 {
514 using type = Number;
515 };
516
517
523 template <typename Number>
524 struct RemoveComplexWrapper<std::complex<Number>>
525 {
526 using type = typename RemoveComplexWrapper<Number>::type;
527 };
528
529
535 template <typename NumberType>
536 struct ExtractData<
537 NumberType,
538 std::enable_if_t<std::is_floating_point<NumberType>::value>>
539 {
543 static const NumberType &
544 value(const NumberType &x)
545 {
546 return x;
547 }
548
549
553 static unsigned int
554 n_directional_derivatives(const NumberType &)
555 {
556 return 0;
557 }
558
559
563 static NumberType
564 directional_derivative(const NumberType &, const unsigned int)
565 {
566 return 0.0;
567 }
568 };
569
570
571
576 template <typename ADNumberType>
577 struct ExtractData<std::complex<ADNumberType>>
578 {
580 "Expected an auto-differentiable number.");
581
582
586 static std::complex<typename ADNumberTraits<ADNumberType>::scalar_type>
587 value(const std::complex<ADNumberType> &x)
588 {
589 return std::complex<
590 typename ADNumberTraits<ADNumberType>::scalar_type>(
591 ExtractData<ADNumberType>::value(x.real()),
592 ExtractData<ADNumberType>::value(x.imag()));
593 }
594
595
599 static unsigned int
600 n_directional_derivatives(const std::complex<ADNumberType> &x)
601 {
602 return ExtractData<ADNumberType>::n_directional_derivatives(x.real());
603 }
604
605
609 static std::complex<
610 typename ADNumberTraits<ADNumberType>::derivative_type>
611 directional_derivative(const std::complex<ADNumberType> &x,
612 const unsigned int direction)
613 {
614 return std::complex<
615 typename ADNumberTraits<ADNumberType>::derivative_type>(
616 ExtractData<ADNumberType>::directional_derivative(x.real(),
617 direction),
618 ExtractData<ADNumberType>::directional_derivative(x.imag(),
619 direction));
620 }
621 };
622
623
624 template <typename T>
625 struct NumberType
626 {
630 template <typename F>
631 static auto
632 value(const F &f, std::enable_if_t<!is_ad_number<F>::value> * = nullptr)
634 {
635 // We call the other function defined in the numbers
636 // header to take care of all of the usual cases.
637 return ::internal::NumberType<T>::value(f);
638 }
639
646 template <typename F>
647 static T
648 value(const F &f,
649 std::enable_if_t<is_ad_number<F>::value &&
650 std::is_floating_point<T>::value> * = nullptr)
651 {
652 // We recursively call this function in case the AD number is a
653 // nested one. The recursion ends when the extracted value is
654 // a floating point number.
655 return NumberType<T>::value(ExtractData<F>::value(f));
656 }
657
664 template <typename F>
665 static T
666 value(const F &f,
667 std::enable_if_t<is_ad_number<F>::value && is_ad_number<T>::value>
668 * = nullptr)
669 {
670 return T(f);
671 }
672 };
673
674 template <typename T>
675 struct NumberType<std::complex<T>>
676 {
680 template <typename F>
681 static auto
682 value(const F &f, std::enable_if_t<!is_ad_number<F>::value> * = nullptr)
683 -> decltype(::internal::NumberType<std::complex<T>>::value(f))
684 {
685 // We call the other function defined in the numbers
686 // header to take care of all of the usual cases.
687 return ::internal::NumberType<std::complex<T>>::value(f);
688 }
689
690
695 template <typename F>
696 static std::complex<T>
697 value(const F &f,
698 std::enable_if_t<is_ad_number<F>::value &&
699 std::is_floating_point<T>::value> * = nullptr)
700 {
701 // We recursively call this function in case the AD number is a
702 // nested one. The recursion ends when the extracted value is
703 // a floating point number.
704 return std::complex<T>(
705 NumberType<T>::value(ExtractData<F>::value(f)));
706 }
707
708 template <typename F>
709 static std::complex<T>
710 value(const std::complex<F> &f)
711 {
712 // Deal with the two parts of the input complex
713 // number individually.
714 return std::complex<T>(NumberType<T>::value(f.real()),
715 NumberType<T>::value(f.imag()));
716 }
717 };
718
719 } // namespace internal
720
721
722
743 template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
744 struct NumberTraits<
745 ScalarType,
746 ADNumberTypeCode,
747 std::enable_if_t<
748 std::is_floating_point<ScalarType>::value ||
749 (boost::is_complex<ScalarType>::value &&
750 std::is_floating_point<
751 typename internal::RemoveComplexWrapper<ScalarType>::type>::value)>>
752 {
756 static constexpr enum NumberTypes type_code = ADNumberTypeCode;
757
758 // The clang compiler does not seem to like these
759 // variables being defined as constant expressions
760 // (the tests <adolc|sacado>/ad_number_traits_02 will
761 // fail with linking errors). However, GCC complains
762 // about the use of non-constant expressions in
763 // std::conditional.
764# ifdef __clang__
765
770 static const bool is_taped;
771
772
777 static const bool is_tapeless;
778
779
784 static const bool is_real_valued;
785
786
791 static const bool is_complex_valued;
792
793
798 static const unsigned int n_supported_derivative_levels;
799
800# else
801
806 static constexpr bool is_taped = internal::ADNumberInfoFromEnum<
807 typename internal::RemoveComplexWrapper<ScalarType>::type,
808 ADNumberTypeCode>::is_taped;
809
810
815 static constexpr bool is_tapeless =
816 !(NumberTraits<ScalarType, ADNumberTypeCode>::is_taped);
817
818
823 static constexpr bool is_real_valued =
824 (!boost::is_complex<ScalarType>::value);
825
826
831 static constexpr bool is_complex_valued =
832 !(NumberTraits<ScalarType, ADNumberTypeCode>::is_real_valued);
833
834
839 static constexpr unsigned int n_supported_derivative_levels =
840 internal::ADNumberInfoFromEnum<
841 typename internal::RemoveComplexWrapper<ScalarType>::type,
842 ADNumberTypeCode>::n_supported_derivative_levels;
843
844# endif
845
846
851 using scalar_type = ScalarType;
852
853
857 using real_type = typename internal::ADNumberInfoFromEnum<
858 typename internal::RemoveComplexWrapper<ScalarType>::type,
859 ADNumberTypeCode>::real_type;
860
861
865 using complex_type = std::complex<real_type>;
866
867
871 using ad_type = typename std::
872 conditional<is_real_valued, real_type, complex_type>::type;
873
877 using derivative_type = typename std::conditional<
878 is_real_valued,
879 typename internal::ADNumberInfoFromEnum<
880 typename internal::RemoveComplexWrapper<ScalarType>::type,
881 ADNumberTypeCode>::derivative_type,
882 std::complex<typename internal::ADNumberInfoFromEnum<
883 typename internal::RemoveComplexWrapper<ScalarType>::type,
884 ADNumberTypeCode>::derivative_type>>::type;
885
886
890 static scalar_type get_scalar_value(const ad_type &x)
891 {
892 // Some tricky conversion cases to consider here:
893 // - Nested AD numbers
894 // - std::complex<double> --> std::complex<float>
895 // e.g. when ScalarType = float and ADNumberTypeCode = adolc_taped
896 // Therefore, we use the internal casting mechanism
897 // provided by the internal::NumberType struct.
899 internal::ExtractData<ad_type>::value(x));
900 }
901
902
906 static derivative_type get_directional_derivative(
907 const ad_type &x, const unsigned int direction)
908 {
909 return internal::ExtractData<ad_type>::directional_derivative(
910 x, direction);
911 }
912
913
918 static unsigned int n_directional_derivatives(const ad_type &x)
919 {
920 return internal::ExtractData<ad_type>::n_directional_derivatives(x);
921 }
922
923
924 static_assert((is_real_valued == true ?
925 std::is_same<ad_type, real_type>::value :
926 std::is_same<ad_type, complex_type>::value),
927 "Incorrect template type selected for ad_type");
928
929 static_assert((is_complex_valued == true ?
930 boost::is_complex<scalar_type>::value :
931 true),
932 "Expected a complex float_type");
933
934 static_assert((is_complex_valued == true ?
935 boost::is_complex<ad_type>::value :
936 true),
937 "Expected a complex ad_type");
938 };
939
940# ifdef __clang__
941
942 template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
943 const bool NumberTraits<
944 ScalarType,
945 ADNumberTypeCode,
946 std::enable_if_t<
947 std::is_floating_point<ScalarType>::value ||
948 (boost::is_complex<ScalarType>::value &&
949 std::is_floating_point<typename internal::RemoveComplexWrapper<
950 ScalarType>::type>::value)>>::is_taped =
951 internal::ADNumberInfoFromEnum<
952 typename internal::RemoveComplexWrapper<ScalarType>::type,
953 ADNumberTypeCode>::is_taped;
954
955
956 template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
957 const bool NumberTraits<
958 ScalarType,
959 ADNumberTypeCode,
960 std::enable_if_t<
961 std::is_floating_point<ScalarType>::value ||
962 (boost::is_complex<ScalarType>::value &&
963 std::is_floating_point<typename internal::RemoveComplexWrapper<
964 ScalarType>::type>::value)>>::is_tapeless =
965 !(NumberTraits<ScalarType, ADNumberTypeCode>::is_taped);
966
967
968 template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
969 const bool NumberTraits<
970 ScalarType,
971 ADNumberTypeCode,
972 std::enable_if_t<
973 std::is_floating_point<ScalarType>::value ||
974 (boost::is_complex<ScalarType>::value &&
975 std::is_floating_point<typename internal::RemoveComplexWrapper<
976 ScalarType>::type>::value)>>::is_real_valued =
977 (!boost::is_complex<ScalarType>::value);
978
979
980 template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
981 const bool NumberTraits<
982 ScalarType,
983 ADNumberTypeCode,
984 std::enable_if_t<
985 std::is_floating_point<ScalarType>::value ||
986 (boost::is_complex<ScalarType>::value &&
987 std::is_floating_point<typename internal::RemoveComplexWrapper<
988 ScalarType>::type>::value)>>::is_complex_valued =
989 !(NumberTraits<ScalarType, ADNumberTypeCode>::is_real_valued);
990
991
992 template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
993 const unsigned int NumberTraits<
994 ScalarType,
995 ADNumberTypeCode,
996 std::enable_if_t<
997 std::is_floating_point<ScalarType>::value ||
998 (boost::is_complex<ScalarType>::value &&
999 std::is_floating_point<typename internal::RemoveComplexWrapper<
1000 ScalarType>::type>::value)>>::n_supported_derivative_levels =
1001 internal::ADNumberInfoFromEnum<
1002 typename internal::RemoveComplexWrapper<ScalarType>::type,
1003 ADNumberTypeCode>::n_supported_derivative_levels;
1004
1005# else
1006
1007 template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
1008 constexpr bool NumberTraits<
1009 ScalarType,
1010 ADNumberTypeCode,
1011 std::enable_if_t<
1012 std::is_floating_point<ScalarType>::value ||
1013 (boost::is_complex<ScalarType>::value &&
1014 std::is_floating_point<typename internal::RemoveComplexWrapper<
1015 ScalarType>::type>::value)>>::is_taped;
1016
1017
1018 template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
1019 constexpr bool NumberTraits<
1020 ScalarType,
1021 ADNumberTypeCode,
1022 std::enable_if_t<
1023 std::is_floating_point<ScalarType>::value ||
1024 (boost::is_complex<ScalarType>::value &&
1025 std::is_floating_point<typename internal::RemoveComplexWrapper<
1026 ScalarType>::type>::value)>>::is_tapeless;
1027
1028
1029 template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
1030 constexpr bool NumberTraits<
1031 ScalarType,
1032 ADNumberTypeCode,
1033 std::enable_if_t<
1034 std::is_floating_point<ScalarType>::value ||
1035 (boost::is_complex<ScalarType>::value &&
1036 std::is_floating_point<typename internal::RemoveComplexWrapper<
1037 ScalarType>::type>::value)>>::is_real_valued;
1038
1039
1040 template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
1041 constexpr bool NumberTraits<
1042 ScalarType,
1043 ADNumberTypeCode,
1044 std::enable_if_t<
1045 std::is_floating_point<ScalarType>::value ||
1046 (boost::is_complex<ScalarType>::value &&
1047 std::is_floating_point<typename internal::RemoveComplexWrapper<
1048 ScalarType>::type>::value)>>::is_complex_valued;
1049
1050
1051 template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
1052 constexpr unsigned int NumberTraits<
1053 ScalarType,
1054 ADNumberTypeCode,
1055 std::enable_if_t<
1056 std::is_floating_point<ScalarType>::value ||
1057 (boost::is_complex<ScalarType>::value &&
1058 std::is_floating_point<typename internal::RemoveComplexWrapper<
1059 ScalarType>::type>::value)>>::n_supported_derivative_levels;
1060
1061# endif
1062
1063
1064
1074 template <typename ScalarType>
1075 struct NumberTraits<
1076 ScalarType,
1078 std::enable_if_t<
1079 std::is_floating_point<ScalarType>::value ||
1080 (boost::is_complex<ScalarType>::value &&
1081 std::is_floating_point<
1082 typename internal::RemoveComplexWrapper<ScalarType>::type>::value)>>
1083 {
1087 static constexpr enum NumberTypes type_code = NumberTypes::none;
1088
1089 // The clang compiler does not seem to like these
1090 // variables being defined as constant expressions
1091 // (the tests <adolc|sacado>/ad_number_traits_02 will
1092 // fail with linking errors). However, GCC complains
1093 // about the use of non-constant expressions in
1094 // std::conditional.
1095# ifdef __clang__
1096
1101 static const bool is_taped;
1102
1103
1108 static const bool is_tapeless;
1109
1110
1115 static const bool is_real_valued;
1116
1117
1122 static const bool is_complex_valued;
1123
1124
1129 static const unsigned int n_supported_derivative_levels;
1130
1131# else
1132
1137 static constexpr bool is_taped = false;
1138
1139
1144 static constexpr bool is_tapeless = false;
1145
1146
1151 static constexpr bool is_real_valued =
1152 (!boost::is_complex<ScalarType>::value);
1153
1154
1159 static constexpr bool is_complex_valued = !is_real_valued;
1160
1161
1166 static constexpr unsigned int n_supported_derivative_levels = 0;
1167
1168# endif
1169
1170
1175 using scalar_type = ScalarType;
1176
1177
1181 using real_type =
1182 typename ::numbers::NumberTraits<scalar_type>::real_type;
1183
1184
1188 using complex_type = std::complex<real_type>;
1189
1190
1194 using ad_type = ScalarType;
1195
1199 using derivative_type = ScalarType;
1200
1201
1205 static scalar_type
1206 get_scalar_value(const ad_type &x)
1207 {
1208 return x;
1209 }
1210
1211
1215 static derivative_type
1216 get_directional_derivative(const ad_type &, const unsigned int)
1217 {
1218 Assert(
1219 false,
1220 ExcMessage(
1221 "Floating point/arithmetic numbers have no directional derivatives."));
1222 return derivative_type();
1223 }
1224
1225
1230 static unsigned int
1231 n_directional_derivatives(const ad_type &)
1232 {
1233 Assert(
1234 false,
1235 ExcMessage(
1236 "Floating point/arithmetic numbers have no directional derivatives."));
1237 return 0;
1238 }
1239 };
1240
1241# ifdef __clang__
1242
1243 template <typename ScalarType>
1244 const bool NumberTraits<
1245 ScalarType,
1247 std::enable_if_t<
1248 std::is_floating_point<ScalarType>::value ||
1249 (boost::is_complex<ScalarType>::value &&
1250 std::is_floating_point<typename internal::RemoveComplexWrapper<
1251 ScalarType>::type>::value)>>::is_taped = false;
1252
1253
1254 template <typename ScalarType>
1255 const bool NumberTraits<
1256 ScalarType,
1258 std::enable_if_t<
1259 std::is_floating_point<ScalarType>::value ||
1260 (boost::is_complex<ScalarType>::value &&
1261 std::is_floating_point<typename internal::RemoveComplexWrapper<
1262 ScalarType>::type>::value)>>::is_tapeless = false;
1263
1264
1265 template <typename ScalarType>
1266 const bool NumberTraits<
1267 ScalarType,
1269 std::enable_if_t<
1270 std::is_floating_point<ScalarType>::value ||
1271 (boost::is_complex<ScalarType>::value &&
1272 std::is_floating_point<typename internal::RemoveComplexWrapper<
1273 ScalarType>::type>::value)>>::is_real_valued =
1274 (!boost::is_complex<ScalarType>::value);
1275
1276
1277 template <typename ScalarType>
1278 const bool NumberTraits<
1279 ScalarType,
1281 std::enable_if_t<
1282 std::is_floating_point<ScalarType>::value ||
1283 (boost::is_complex<ScalarType>::value &&
1284 std::is_floating_point<typename internal::RemoveComplexWrapper<
1285 ScalarType>::type>::value)>>::is_complex_valued =
1286 !(NumberTraits<ScalarType, NumberTypes::none>::is_real_valued);
1287
1288
1289 template <typename ScalarType>
1290 const unsigned int NumberTraits<
1291 ScalarType,
1293 std::enable_if_t<
1294 std::is_floating_point<ScalarType>::value ||
1295 (boost::is_complex<ScalarType>::value &&
1296 std::is_floating_point<typename internal::RemoveComplexWrapper<
1297 ScalarType>::type>::value)>>::n_supported_derivative_levels = 0;
1298
1299# else
1300
1301 template <typename ScalarType>
1302 constexpr bool NumberTraits<
1303 ScalarType,
1305 std::enable_if_t<
1306 std::is_floating_point<ScalarType>::value ||
1307 (boost::is_complex<ScalarType>::value &&
1308 std::is_floating_point<typename internal::RemoveComplexWrapper<
1309 ScalarType>::type>::value)>>::is_taped;
1310
1311
1312 template <typename ScalarType>
1313 constexpr bool NumberTraits<
1314 ScalarType,
1316 std::enable_if_t<
1317 std::is_floating_point<ScalarType>::value ||
1318 (boost::is_complex<ScalarType>::value &&
1319 std::is_floating_point<typename internal::RemoveComplexWrapper<
1320 ScalarType>::type>::value)>>::is_tapeless;
1321
1322
1323 template <typename ScalarType>
1324 constexpr bool NumberTraits<
1325 ScalarType,
1327 std::enable_if_t<
1328 std::is_floating_point<ScalarType>::value ||
1329 (boost::is_complex<ScalarType>::value &&
1330 std::is_floating_point<typename internal::RemoveComplexWrapper<
1331 ScalarType>::type>::value)>>::is_real_valued;
1332
1333
1334 template <typename ScalarType>
1335 constexpr bool NumberTraits<
1336 ScalarType,
1338 std::enable_if_t<
1339 std::is_floating_point<ScalarType>::value ||
1340 (boost::is_complex<ScalarType>::value &&
1341 std::is_floating_point<typename internal::RemoveComplexWrapper<
1342 ScalarType>::type>::value)>>::is_complex_valued;
1343
1344
1345 template <typename ScalarType>
1346 constexpr unsigned int NumberTraits<
1347 ScalarType,
1349 std::enable_if_t<
1350 std::is_floating_point<ScalarType>::value ||
1351 (boost::is_complex<ScalarType>::value &&
1352 std::is_floating_point<typename internal::RemoveComplexWrapper<
1353 ScalarType>::type>::value)>>::n_supported_derivative_levels;
1354
1355# endif
1356
1357
1376 template <typename ScalarType>
1377 struct ADNumberTraits<
1378 ScalarType,
1379 std::enable_if_t<std::is_floating_point<ScalarType>::value>>
1380 : NumberTraits<ScalarType, NumberTypes::none>
1381 {};
1382
1386 template <typename ComplexScalarType>
1387 struct ADNumberTraits<
1388 ComplexScalarType,
1389 std::enable_if_t<
1390 boost::is_complex<ComplexScalarType>::value &&
1391 std::is_floating_point<typename ComplexScalarType::value_type>::value>>
1392 : NumberTraits<ComplexScalarType, NumberTypes::none>
1393 {};
1394
1395 } // namespace AD
1396} // namespace Differentiation
1397
1398#endif // DOXYGEN
1399
1401
1402#endif
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:472
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:473
#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:702