Reference documentation for deal.II version 9.4.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\}}\)
ad_number_traits.h
Go to the documentation of this file.
1// ---------------------------------------------------------------------
2//
3// Copyright (C) 2016 - 2020 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 typename std::enable_if<
328 std::is_floating_point<ScalarType>::value>::type>
329 {
330 static const bool is_taped = false;
331 using real_type = ScalarType;
332 using derivative_type = ScalarType;
333 static const unsigned int n_supported_derivative_levels = 0;
334 };
335
336
342 template <typename ScalarType>
343 struct Marking<ScalarType,
344 typename std::enable_if<
345 std::is_floating_point<ScalarType>::value>::type>
346 {
354 template <typename ADNumberType>
355 static void
356 independent_variable(const ScalarType &in,
357 const unsigned int,
358 const unsigned int,
359 ADNumberType &out)
360 {
361 out = in;
362 }
363
364 /*
365 * Initialize the state of a dependent variable.
366 */
367 template <typename ADNumberType>
368 static void
369 dependent_variable(ADNumberType &, const ScalarType &)
370 {
372 false,
374 "Floating point numbers cannot be marked as dependent variables."));
375 }
376 };
377
378
382 template <typename ADNumberType>
383 struct Marking<
384 ADNumberType,
385 typename std::enable_if<boost::is_complex<ADNumberType>::value>::type>
386 {
387 /*
388 * Initialize the state of an independent variable.
389 */
390 template <typename ScalarType>
391 static void
392 independent_variable(const ScalarType &in,
393 const unsigned int,
394 const unsigned int,
395 ADNumberType &out)
396 {
398 false,
400 "Marking for complex numbers has not yet been implemented."));
401 out = in;
402 }
403
404 /*
405 * Initialize the state of a dependent variable.
406 */
407 template <typename ScalarType>
408 static void
409 dependent_variable(ADNumberType &, const ScalarType &)
410 {
412 false,
414 "Marking for complex numbers has not yet been implemented."));
415 }
416 };
417
418 } // namespace internal
419
420
421 template <typename NumberType, typename>
422 struct is_taped_ad_number : std::false_type
423 {};
424
425
426 template <typename NumberType, typename>
427 struct is_tapeless_ad_number : std::false_type
428 {};
429
430
431 template <typename NumberType, typename>
432 struct is_real_valued_ad_number : std::false_type
433 {};
434
435
436 template <typename NumberType, typename>
437 struct is_complex_valued_ad_number : std::false_type
438 {};
439
440
446 template <typename NumberType>
447 struct is_ad_number
448 : internal::HasRequiredADInfo<
449 ADNumberTraits<typename std::decay<NumberType>::type>>
450 {};
451
452
457 template <typename NumberType>
458 struct is_taped_ad_number<
459 NumberType,
460 typename std::enable_if<
461 ADNumberTraits<typename std::decay<NumberType>::type>::is_taped>::type>
462 : std::true_type
463 {};
464
465
470 template <typename NumberType>
471 struct is_tapeless_ad_number<
472 NumberType,
473 typename std::enable_if<ADNumberTraits<
474 typename std::decay<NumberType>::type>::is_tapeless>::type>
475 : std::true_type
476 {};
477
478
484 template <typename NumberType>
485 struct is_real_valued_ad_number<
486 NumberType,
487 typename std::enable_if<ADNumberTraits<
488 typename std::decay<NumberType>::type>::is_real_valued>::type>
489 : std::true_type
490 {};
491
492
498 template <typename NumberType>
499 struct is_complex_valued_ad_number<
500 NumberType,
501 typename std::enable_if<ADNumberTraits<
502 typename std::decay<NumberType>::type>::is_complex_valued>::type>
503 : std::true_type
504 {};
505
506
507 namespace internal
508 {
513 template <typename Number>
514 struct RemoveComplexWrapper
515 {
516 using type = Number;
517 };
518
519
525 template <typename Number>
526 struct RemoveComplexWrapper<std::complex<Number>>
527 {
528 using type = typename RemoveComplexWrapper<Number>::type;
529 };
530
531
537 template <typename NumberType>
538 struct ExtractData<NumberType,
539 typename std::enable_if<
540 std::is_floating_point<NumberType>::value>::type>
541 {
545 static const NumberType &
546 value(const NumberType &x)
547 {
548 return x;
549 }
550
551
555 static unsigned int
556 n_directional_derivatives(const NumberType &)
557 {
558 return 0;
559 }
560
561
565 static NumberType
566 directional_derivative(const NumberType &, const unsigned int)
567 {
568 return 0.0;
569 }
570 };
571
572
573
578 template <typename ADNumberType>
579 struct ExtractData<std::complex<ADNumberType>>
580 {
582 "Expected an auto-differentiable number.");
583
584
588 static std::complex<typename ADNumberTraits<ADNumberType>::scalar_type>
589 value(const std::complex<ADNumberType> &x)
590 {
591 return std::complex<
592 typename ADNumberTraits<ADNumberType>::scalar_type>(
593 ExtractData<ADNumberType>::value(x.real()),
594 ExtractData<ADNumberType>::value(x.imag()));
595 }
596
597
601 static unsigned int
602 n_directional_derivatives(const std::complex<ADNumberType> &x)
603 {
604 return ExtractData<ADNumberType>::n_directional_derivatives(x.real());
605 }
606
607
611 static std::complex<
612 typename ADNumberTraits<ADNumberType>::derivative_type>
613 directional_derivative(const std::complex<ADNumberType> &x,
614 const unsigned int direction)
615 {
616 return std::complex<
617 typename ADNumberTraits<ADNumberType>::derivative_type>(
618 ExtractData<ADNumberType>::directional_derivative(x.real(),
619 direction),
620 ExtractData<ADNumberType>::directional_derivative(x.imag(),
621 direction));
622 }
623 };
624
625
626 template <typename T>
627 struct NumberType
628 {
632 template <typename F>
633 static auto
634 value(const F &f,
635 typename std::enable_if<!is_ad_number<F>::value>::type * =
636 nullptr) -> decltype(::internal::NumberType<T>::value(f))
637 {
638 // We call the other function defined in the numbers
639 // header to take care of all of the usual cases.
640 return ::internal::NumberType<T>::value(f);
641 }
642
649 template <typename F>
650 static T
651 value(const F &f,
652 typename std::enable_if<is_ad_number<F>::value &&
653 std::is_floating_point<T>::value>::type
654 * = nullptr)
655 {
656 // We recursively call this function in case the AD number is a
657 // nested one. The recursion ends when the extracted value is
658 // a floating point number.
659 return NumberType<T>::value(ExtractData<F>::value(f));
660 }
661
668 template <typename F>
669 static T
670 value(const F &f,
671 typename std::enable_if<is_ad_number<F>::value &&
672 is_ad_number<T>::value>::type * = nullptr)
673 {
674 return T(f);
675 }
676 };
677
678 template <typename T>
679 struct NumberType<std::complex<T>>
680 {
684 template <typename F>
685 static auto
686 value(
687 const F &f,
688 typename std::enable_if<!is_ad_number<F>::value>::type * = nullptr)
689 -> decltype(::internal::NumberType<std::complex<T>>::value(f))
690 {
691 // We call the other function defined in the numbers
692 // header to take care of all of the usual cases.
693 return ::internal::NumberType<std::complex<T>>::value(f);
694 }
695
696
701 template <typename F>
702 static std::complex<T>
703 value(const F &f,
704 typename std::enable_if<is_ad_number<F>::value &&
705 std::is_floating_point<T>::value>::type
706 * = nullptr)
707 {
708 // We recursively call this function in case the AD number is a
709 // nested one. The recursion ends when the extracted value is
710 // a floating point number.
711 return std::complex<T>(
712 NumberType<T>::value(ExtractData<F>::value(f)));
713 }
714
715 template <typename F>
716 static std::complex<T>
717 value(const std::complex<F> &f)
718 {
719 // Deal with the two parts of the input complex
720 // number individually.
721 return std::complex<T>(NumberType<T>::value(f.real()),
722 NumberType<T>::value(f.imag()));
723 }
724 };
725
726 } // namespace internal
727
728
729
750 template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
751 struct NumberTraits<
752 ScalarType,
753 ADNumberTypeCode,
754 typename std::enable_if<
755 std::is_floating_point<ScalarType>::value ||
756 (boost::is_complex<ScalarType>::value &&
757 std::is_floating_point<typename internal::RemoveComplexWrapper<
758 ScalarType>::type>::value)>::type>
759 {
763 static constexpr enum NumberTypes type_code = ADNumberTypeCode;
764
765 // The clang compiler does not seem to like these
766 // variables being defined as constant expressions
767 // (the tests <adolc|sacado>/ad_number_traits_02 will
768 // fail with linking errors). However, GCC complains
769 // about the use of non-constant expressions in
770 // std::conditional.
771# ifdef __clang__
772
777 static const bool is_taped;
778
779
784 static const bool is_tapeless;
785
786
791 static const bool is_real_valued;
792
793
798 static const bool is_complex_valued;
799
800
805 static const unsigned int n_supported_derivative_levels;
806
807# else
808
813 static constexpr bool is_taped = internal::ADNumberInfoFromEnum<
814 typename internal::RemoveComplexWrapper<ScalarType>::type,
815 ADNumberTypeCode>::is_taped;
816
817
822 static constexpr bool is_tapeless =
823 !(NumberTraits<ScalarType, ADNumberTypeCode>::is_taped);
824
825
830 static constexpr bool is_real_valued =
831 (!boost::is_complex<ScalarType>::value);
832
833
838 static constexpr bool is_complex_valued =
839 !(NumberTraits<ScalarType, ADNumberTypeCode>::is_real_valued);
840
841
846 static constexpr unsigned int n_supported_derivative_levels =
847 internal::ADNumberInfoFromEnum<
848 typename internal::RemoveComplexWrapper<ScalarType>::type,
849 ADNumberTypeCode>::n_supported_derivative_levels;
850
851# endif
852
853
858 using scalar_type = ScalarType;
859
860
864 using real_type = typename internal::ADNumberInfoFromEnum<
865 typename internal::RemoveComplexWrapper<ScalarType>::type,
866 ADNumberTypeCode>::real_type;
867
868
872 using complex_type = std::complex<real_type>;
873
874
878 using ad_type = typename std::
879 conditional<is_real_valued, real_type, complex_type>::type;
880
884 using derivative_type = typename std::conditional<
885 is_real_valued,
886 typename internal::ADNumberInfoFromEnum<
887 typename internal::RemoveComplexWrapper<ScalarType>::type,
888 ADNumberTypeCode>::derivative_type,
889 std::complex<typename internal::ADNumberInfoFromEnum<
890 typename internal::RemoveComplexWrapper<ScalarType>::type,
891 ADNumberTypeCode>::derivative_type>>::type;
892
893
897 static scalar_type get_scalar_value(const ad_type &x)
898 {
899 // Some tricky conversion cases to consider here:
900 // - Nested AD numbers
901 // - std::complex<double> --> std::complex<float>
902 // e.g. when ScalarType = float and ADNumberTypeCode = adolc_taped
903 // Therefore, we use the internal casting mechanism
904 // provided by the internal::NumberType struct.
906 internal::ExtractData<ad_type>::value(x));
907 }
908
909
913 static derivative_type get_directional_derivative(
914 const ad_type &x, const unsigned int direction)
915 {
916 return internal::ExtractData<ad_type>::directional_derivative(
917 x, direction);
918 }
919
920
925 static unsigned int n_directional_derivatives(const ad_type &x)
926 {
927 return internal::ExtractData<ad_type>::n_directional_derivatives(x);
928 }
929
930
931 static_assert((is_real_valued == true ?
932 std::is_same<ad_type, real_type>::value :
933 std::is_same<ad_type, complex_type>::value),
934 "Incorrect template type selected for ad_type");
935
936 static_assert((is_complex_valued == true ?
937 boost::is_complex<scalar_type>::value :
938 true),
939 "Expected a complex float_type");
940
941 static_assert((is_complex_valued == true ?
942 boost::is_complex<ad_type>::value :
943 true),
944 "Expected a complex ad_type");
945 };
946
947# ifdef __clang__
948
949 template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
950 const bool NumberTraits<
951 ScalarType,
952 ADNumberTypeCode,
953 typename std::enable_if<
954 std::is_floating_point<ScalarType>::value ||
955 (boost::is_complex<ScalarType>::value &&
956 std::is_floating_point<typename internal::RemoveComplexWrapper<
957 ScalarType>::type>::value)>::type>::is_taped =
958 internal::ADNumberInfoFromEnum<
959 typename internal::RemoveComplexWrapper<ScalarType>::type,
960 ADNumberTypeCode>::is_taped;
961
962
963 template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
964 const bool NumberTraits<
965 ScalarType,
966 ADNumberTypeCode,
967 typename std::enable_if<
968 std::is_floating_point<ScalarType>::value ||
969 (boost::is_complex<ScalarType>::value &&
970 std::is_floating_point<typename internal::RemoveComplexWrapper<
971 ScalarType>::type>::value)>::type>::is_tapeless =
972 !(NumberTraits<ScalarType, ADNumberTypeCode>::is_taped);
973
974
975 template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
976 const bool NumberTraits<
977 ScalarType,
978 ADNumberTypeCode,
979 typename std::enable_if<
980 std::is_floating_point<ScalarType>::value ||
981 (boost::is_complex<ScalarType>::value &&
982 std::is_floating_point<typename internal::RemoveComplexWrapper<
983 ScalarType>::type>::value)>::type>::is_real_valued =
984 (!boost::is_complex<ScalarType>::value);
985
986
987 template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
988 const bool NumberTraits<
989 ScalarType,
990 ADNumberTypeCode,
991 typename std::enable_if<
992 std::is_floating_point<ScalarType>::value ||
993 (boost::is_complex<ScalarType>::value &&
994 std::is_floating_point<typename internal::RemoveComplexWrapper<
995 ScalarType>::type>::value)>::type>::is_complex_valued =
996 !(NumberTraits<ScalarType, ADNumberTypeCode>::is_real_valued);
997
998
999 template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
1000 const unsigned int NumberTraits<
1001 ScalarType,
1002 ADNumberTypeCode,
1003 typename std::enable_if<
1004 std::is_floating_point<ScalarType>::value ||
1005 (boost::is_complex<ScalarType>::value &&
1006 std::is_floating_point<typename internal::RemoveComplexWrapper<
1007 ScalarType>::type>::value)>::type>::n_supported_derivative_levels =
1008 internal::ADNumberInfoFromEnum<
1009 typename internal::RemoveComplexWrapper<ScalarType>::type,
1010 ADNumberTypeCode>::n_supported_derivative_levels;
1011
1012# else
1013
1014 template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
1015 constexpr bool NumberTraits<
1016 ScalarType,
1017 ADNumberTypeCode,
1018 typename std::enable_if<
1019 std::is_floating_point<ScalarType>::value ||
1020 (boost::is_complex<ScalarType>::value &&
1021 std::is_floating_point<typename internal::RemoveComplexWrapper<
1022 ScalarType>::type>::value)>::type>::is_taped;
1023
1024
1025 template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
1026 constexpr bool NumberTraits<
1027 ScalarType,
1028 ADNumberTypeCode,
1029 typename std::enable_if<
1030 std::is_floating_point<ScalarType>::value ||
1031 (boost::is_complex<ScalarType>::value &&
1032 std::is_floating_point<typename internal::RemoveComplexWrapper<
1033 ScalarType>::type>::value)>::type>::is_tapeless;
1034
1035
1036 template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
1037 constexpr bool NumberTraits<
1038 ScalarType,
1039 ADNumberTypeCode,
1040 typename std::enable_if<
1041 std::is_floating_point<ScalarType>::value ||
1042 (boost::is_complex<ScalarType>::value &&
1043 std::is_floating_point<typename internal::RemoveComplexWrapper<
1044 ScalarType>::type>::value)>::type>::is_real_valued;
1045
1046
1047 template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
1048 constexpr bool NumberTraits<
1049 ScalarType,
1050 ADNumberTypeCode,
1051 typename std::enable_if<
1052 std::is_floating_point<ScalarType>::value ||
1053 (boost::is_complex<ScalarType>::value &&
1054 std::is_floating_point<typename internal::RemoveComplexWrapper<
1055 ScalarType>::type>::value)>::type>::is_complex_valued;
1056
1057
1058 template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
1059 constexpr unsigned int NumberTraits<
1060 ScalarType,
1061 ADNumberTypeCode,
1062 typename std::enable_if<
1063 std::is_floating_point<ScalarType>::value ||
1064 (boost::is_complex<ScalarType>::value &&
1065 std::is_floating_point<typename internal::RemoveComplexWrapper<
1066 ScalarType>::type>::value)>::type>::n_supported_derivative_levels;
1067
1068# endif
1069
1070
1071
1081 template <typename ScalarType>
1082 struct NumberTraits<
1083 ScalarType,
1085 typename std::enable_if<
1086 std::is_floating_point<ScalarType>::value ||
1087 (boost::is_complex<ScalarType>::value &&
1088 std::is_floating_point<typename internal::RemoveComplexWrapper<
1089 ScalarType>::type>::value)>::type>
1090 {
1094 static constexpr enum NumberTypes type_code = NumberTypes::none;
1095
1096 // The clang compiler does not seem to like these
1097 // variables being defined as constant expressions
1098 // (the tests <adolc|sacado>/ad_number_traits_02 will
1099 // fail with linking errors). However, GCC complains
1100 // about the use of non-constant expressions in
1101 // std::conditional.
1102# ifdef __clang__
1103
1108 static const bool is_taped;
1109
1110
1115 static const bool is_tapeless;
1116
1117
1122 static const bool is_real_valued;
1123
1124
1129 static const bool is_complex_valued;
1130
1131
1136 static const unsigned int n_supported_derivative_levels;
1137
1138# else
1139
1144 static constexpr bool is_taped = false;
1145
1146
1151 static constexpr bool is_tapeless = false;
1152
1153
1158 static constexpr bool is_real_valued =
1159 (!boost::is_complex<ScalarType>::value);
1160
1161
1166 static constexpr bool is_complex_valued = !is_real_valued;
1167
1168
1173 static constexpr unsigned int n_supported_derivative_levels = 0;
1174
1175# endif
1176
1177
1182 using scalar_type = ScalarType;
1183
1184
1188 using real_type =
1189 typename ::numbers::NumberTraits<scalar_type>::real_type;
1190
1191
1195 using complex_type = std::complex<real_type>;
1196
1197
1201 using ad_type = ScalarType;
1202
1206 using derivative_type = ScalarType;
1207
1208
1212 static scalar_type
1213 get_scalar_value(const ad_type &x)
1214 {
1215 return x;
1216 }
1217
1218
1222 static derivative_type
1223 get_directional_derivative(const ad_type &, const unsigned int)
1224 {
1225 Assert(
1226 false,
1227 ExcMessage(
1228 "Floating point/arithmetic numbers have no directional derivatives."));
1229 return derivative_type();
1230 }
1231
1232
1237 static unsigned int
1238 n_directional_derivatives(const ad_type &)
1239 {
1240 Assert(
1241 false,
1242 ExcMessage(
1243 "Floating point/arithmetic numbers have no directional derivatives."));
1244 return 0;
1245 }
1246 };
1247
1248# ifdef __clang__
1249
1250 template <typename ScalarType>
1251 const bool NumberTraits<
1252 ScalarType,
1254 typename std::enable_if<
1255 std::is_floating_point<ScalarType>::value ||
1256 (boost::is_complex<ScalarType>::value &&
1257 std::is_floating_point<typename internal::RemoveComplexWrapper<
1258 ScalarType>::type>::value)>::type>::is_taped = false;
1259
1260
1261 template <typename ScalarType>
1262 const bool NumberTraits<
1263 ScalarType,
1265 typename std::enable_if<
1266 std::is_floating_point<ScalarType>::value ||
1267 (boost::is_complex<ScalarType>::value &&
1268 std::is_floating_point<typename internal::RemoveComplexWrapper<
1269 ScalarType>::type>::value)>::type>::is_tapeless = false;
1270
1271
1272 template <typename ScalarType>
1273 const bool NumberTraits<
1274 ScalarType,
1276 typename std::enable_if<
1277 std::is_floating_point<ScalarType>::value ||
1278 (boost::is_complex<ScalarType>::value &&
1279 std::is_floating_point<typename internal::RemoveComplexWrapper<
1280 ScalarType>::type>::value)>::type>::is_real_valued =
1281 (!boost::is_complex<ScalarType>::value);
1282
1283
1284 template <typename ScalarType>
1285 const bool NumberTraits<
1286 ScalarType,
1288 typename std::enable_if<
1289 std::is_floating_point<ScalarType>::value ||
1290 (boost::is_complex<ScalarType>::value &&
1291 std::is_floating_point<typename internal::RemoveComplexWrapper<
1292 ScalarType>::type>::value)>::type>::is_complex_valued =
1293 !(NumberTraits<ScalarType, NumberTypes::none>::is_real_valued);
1294
1295
1296 template <typename ScalarType>
1297 const unsigned int NumberTraits<
1298 ScalarType,
1300 typename std::enable_if<
1301 std::is_floating_point<ScalarType>::value ||
1302 (boost::is_complex<ScalarType>::value &&
1303 std::is_floating_point<typename internal::RemoveComplexWrapper<
1304 ScalarType>::type>::value)>::type>::n_supported_derivative_levels =
1305 0;
1306
1307# else
1308
1309 template <typename ScalarType>
1310 constexpr bool NumberTraits<
1311 ScalarType,
1313 typename std::enable_if<
1314 std::is_floating_point<ScalarType>::value ||
1315 (boost::is_complex<ScalarType>::value &&
1316 std::is_floating_point<typename internal::RemoveComplexWrapper<
1317 ScalarType>::type>::value)>::type>::is_taped;
1318
1319
1320 template <typename ScalarType>
1321 constexpr bool NumberTraits<
1322 ScalarType,
1324 typename std::enable_if<
1325 std::is_floating_point<ScalarType>::value ||
1326 (boost::is_complex<ScalarType>::value &&
1327 std::is_floating_point<typename internal::RemoveComplexWrapper<
1328 ScalarType>::type>::value)>::type>::is_tapeless;
1329
1330
1331 template <typename ScalarType>
1332 constexpr bool NumberTraits<
1333 ScalarType,
1335 typename std::enable_if<
1336 std::is_floating_point<ScalarType>::value ||
1337 (boost::is_complex<ScalarType>::value &&
1338 std::is_floating_point<typename internal::RemoveComplexWrapper<
1339 ScalarType>::type>::value)>::type>::is_real_valued;
1340
1341
1342 template <typename ScalarType>
1343 constexpr bool NumberTraits<
1344 ScalarType,
1346 typename std::enable_if<
1347 std::is_floating_point<ScalarType>::value ||
1348 (boost::is_complex<ScalarType>::value &&
1349 std::is_floating_point<typename internal::RemoveComplexWrapper<
1350 ScalarType>::type>::value)>::type>::is_complex_valued;
1351
1352
1353 template <typename ScalarType>
1354 constexpr unsigned int NumberTraits<
1355 ScalarType,
1357 typename std::enable_if<
1358 std::is_floating_point<ScalarType>::value ||
1359 (boost::is_complex<ScalarType>::value &&
1360 std::is_floating_point<typename internal::RemoveComplexWrapper<
1361 ScalarType>::type>::value)>::type>::n_supported_derivative_levels;
1362
1363# endif
1364
1365
1384 template <typename ScalarType>
1385 struct ADNumberTraits<
1386 ScalarType,
1387 typename std::enable_if<std::is_floating_point<ScalarType>::value>::type>
1388 : NumberTraits<ScalarType, NumberTypes::none>
1389 {};
1390
1394 template <typename ComplexScalarType>
1395 struct ADNumberTraits<
1396 ComplexScalarType,
1397 typename std::enable_if<
1398 boost::is_complex<ComplexScalarType>::value &&
1399 std::is_floating_point<typename ComplexScalarType::value_type>::value>::
1400 type> : NumberTraits<ComplexScalarType, NumberTypes::none>
1401 {};
1402
1403 } // namespace AD
1404} // namespace Differentiation
1405
1406#endif // DOXYGEN
1407
1409
1410#endif
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:442
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:443
#define Assert(cond, exc)
Definition: exceptions.h:1473
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
Definition: exceptions.h:1583
static const char T
Tensor< 2, dim, Number > F(const Tensor< 2, dim, Number > &Grad_u)
STL namespace.
static constexpr const T & value(const T &t)
Definition: numbers.h:705