Reference documentation for deal.II version Git a0b41b6d0f 2020-02-26 20:08:13 -0600
\(\newcommand{\vcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\vcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
ad_number_traits.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2016 - 2017 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 
21 #include <deal.II/base/exceptions.h>
22 #include <deal.II/base/numbers.h>
23 
24 #include <deal.II/differentiation/ad/ad_number_types.h>
25 
26 #include <boost/type_traits.hpp>
27 
28 #include <complex>
29 #include <type_traits>
30 
31 DEAL_II_NAMESPACE_OPEN
32 
33 namespace Differentiation
34 {
35  namespace AD
36  {
50  template <typename ScalarType,
51  enum NumberTypes ADNumberTypeCode,
52  typename T = void>
53  struct NumberTraits;
54 
55 
56 
71  template <typename ADNumberType, typename T = void>
73 
74 
79  namespace internal
80  {
81  // The following three classes, namely ADNumberInfoFromEnum, Marking, and
82  // ExtractData, are those that need to be implemented for each new
83  // auto-differentiable number type. This information is then used by
84  // NumberTraits and ADNumberTraits to provide a uniform interface, as used
85  // by our drivers, to the underlying number types.
86 
87 
113  template <typename ScalarType,
114  enum NumberTypes ADNumberTypeCode,
115  typename = void>
117 
118 
150  template <typename ADNumberType, typename T = void>
151  struct Marking;
152 
153 
185  template <typename ADNumberType, typename T = void>
186  struct ExtractData;
187 
188 
203  template <typename ADNumberTrait, typename T = void>
205 
206 
223  template <typename T>
224  struct NumberType;
225 
226 
233  template <typename Number>
235 
236  } // namespace internal
237 
238 
247  template <typename NumberType>
248  struct is_ad_number;
249 
250 
259  template <typename NumberType, typename = void>
261 
262 
271  template <typename NumberType, typename = void>
273 
274 
283  template <typename NumberType, typename = void>
285 
286 
295  template <typename NumberType, typename = void>
297 
298  } // namespace AD
299 } // namespace Differentiation
300 
301 
302 /* ----------- inline and template functions and specializations ----------- */
303 
304 
305 #ifndef DOXYGEN
306 
307 
308 namespace Differentiation
309 {
310  namespace AD
311  {
312  namespace internal
313  {
314  template <typename ADNumberTrait, typename>
315  struct HasRequiredADInfo : std::false_type
316  {};
317 
318 
330  template <typename ADNumberTrait>
331  struct HasRequiredADInfo<
332  ADNumberTrait,
333  decltype((void)ADNumberTrait::type_code,
334  (void)ADNumberTrait::is_taped,
335  (void)std::declval<typename ADNumberTrait::real_type>(),
336  (void)std::declval<typename ADNumberTrait::derivative_type>(),
337  void())>
338  : std::conditional<
339  std::is_floating_point<typename ADNumberTrait::real_type>::value,
340  std::false_type,
341  std::true_type>::type
342  {};
343 
344 
349  template <typename ScalarType>
350  struct ADNumberInfoFromEnum<
351  ScalarType,
353  typename std::enable_if<
354  std::is_floating_point<ScalarType>::value>::type>
355  {
356  static const bool is_taped = false;
357  using real_type = ScalarType;
358  using derivative_type = ScalarType;
359  static const unsigned int n_supported_derivative_levels = 0;
360  };
361 
362 
368  template <typename ScalarType>
369  struct Marking<ScalarType,
370  typename std::enable_if<
371  std::is_floating_point<ScalarType>::value>::type>
372  {
380  template <typename ADNumberType>
381  static void
382  independent_variable(const ScalarType &in,
383  const unsigned int,
384  const unsigned int,
385  ADNumberType &out)
386  {
387  out = in;
388  }
389 
390  /*
391  * Initialize the state of a dependent variable.
392  */
393  template <typename ADNumberType>
394  static void
395  dependent_variable(ADNumberType &, const ScalarType &)
396  {
397  AssertThrow(
398  false,
399  ExcMessage(
400  "Floating point numbers cannot be marked as dependent variables."));
401  }
402  };
403 
404 
408  template <typename ADNumberType>
409  struct Marking<
410  ADNumberType,
411  typename std::enable_if<boost::is_complex<ADNumberType>::value>::type>
412  {
413  /*
414  * Initialize the state of an independent variable.
415  */
416  template <typename ScalarType>
417  static void
418  independent_variable(const ScalarType &in,
419  const unsigned int,
420  const unsigned int,
421  ADNumberType &out)
422  {
423  AssertThrow(
424  false,
425  ExcMessage(
426  "Marking for complex numbers has not yet been implemented."));
427  out = in;
428  }
429 
430  /*
431  * Initialize the state of a dependent variable.
432  */
433  template <typename ScalarType>
434  static void
435  dependent_variable(ADNumberType &, const ScalarType &)
436  {
437  AssertThrow(
438  false,
439  ExcMessage(
440  "Marking for complex numbers has not yet been implemented."));
441  }
442  };
443 
444  } // namespace internal
445 
446 
447  template <typename NumberType, typename>
448  struct is_taped_ad_number : std::false_type
449  {};
450 
451 
452  template <typename NumberType, typename>
453  struct is_tapeless_ad_number : std::false_type
454  {};
455 
456 
457  template <typename NumberType, typename>
458  struct is_real_valued_ad_number : std::false_type
459  {};
460 
461 
462  template <typename NumberType, typename>
463  struct is_complex_valued_ad_number : std::false_type
464  {};
465 
466 
472  template <typename NumberType>
473  struct is_ad_number
475  ADNumberTraits<typename std::decay<NumberType>::type>>
476  {};
477 
478 
483  template <typename NumberType>
484  struct is_taped_ad_number<
485  NumberType,
486  typename std::enable_if<
487  ADNumberTraits<typename std::decay<NumberType>::type>::is_taped>::type>
488  : std::true_type
489  {};
490 
491 
496  template <typename NumberType>
497  struct is_tapeless_ad_number<
498  NumberType,
499  typename std::enable_if<ADNumberTraits<
500  typename std::decay<NumberType>::type>::is_tapeless>::type>
501  : std::true_type
502  {};
503 
504 
510  template <typename NumberType>
512  NumberType,
513  typename std::enable_if<ADNumberTraits<
514  typename std::decay<NumberType>::type>::is_real_valued>::type>
515  : std::true_type
516  {};
517 
518 
524  template <typename NumberType>
526  NumberType,
527  typename std::enable_if<ADNumberTraits<
528  typename std::decay<NumberType>::type>::is_complex_valued>::type>
529  : std::true_type
530  {};
531 
532 
533  namespace internal
534  {
539  template <typename Number>
540  struct RemoveComplexWrapper
541  {
542  using type = Number;
543  };
544 
545 
551  template <typename Number>
552  struct RemoveComplexWrapper<std::complex<Number>>
553  {
554  using type = typename RemoveComplexWrapper<Number>::type;
555  };
556 
557 
563  template <typename NumberType>
564  struct ExtractData<NumberType,
565  typename std::enable_if<
566  std::is_floating_point<NumberType>::value>::type>
567  {
571  static const NumberType &
572  value(const NumberType &x)
573  {
574  return x;
575  }
576 
577 
581  static unsigned int
582  n_directional_derivatives(const NumberType &)
583  {
584  return 0;
585  }
586 
587 
591  static NumberType
592  directional_derivative(const NumberType &, const unsigned int)
593  {
594  return 0.0;
595  }
596  };
597 
598 
599 
604  template <typename ADNumberType>
605  struct ExtractData<std::complex<ADNumberType>>
606  {
608  "Expected an auto-differentiable number.");
609 
610 
614  static std::complex<typename ADNumberTraits<ADNumberType>::scalar_type>
615  value(const std::complex<ADNumberType> &x)
616  {
617  return std::complex<
619  ExtractData<ADNumberType>::value(x.real()),
620  ExtractData<ADNumberType>::value(x.imag()));
621  }
622 
623 
627  static unsigned int
628  n_directional_derivatives(const std::complex<ADNumberType> &x)
629  {
630  return ExtractData<ADNumberType>::n_directional_derivatives(x.real());
631  }
632 
633 
637  static std::complex<
639  directional_derivative(const std::complex<ADNumberType> &x,
640  const unsigned int direction)
641  {
642  return std::complex<
644  ExtractData<ADNumberType>::directional_derivative(x.real(),
645  direction),
646  ExtractData<ADNumberType>::directional_derivative(x.imag(),
647  direction));
648  }
649  };
650 
651 
652  template <typename T>
653  struct NumberType
654  {
658  template <typename F>
659  static auto
660  value(const F &f,
661  typename std::enable_if<!is_ad_number<F>::value>::type * =
662  nullptr) -> decltype(::internal::NumberType<T>::value(f))
663  {
664  // We call the other function defined in the numbers
665  // header to take care of all of the usual cases.
666  return ::internal::NumberType<T>::value(f);
667  }
668 
675  template <typename F>
676  static T
677  value(const F &f,
678  typename std::enable_if<is_ad_number<F>::value &&
679  std::is_floating_point<T>::value>::type
680  * = nullptr)
681  {
682  // We recursively call this function in case the AD number is a
683  // nested one. The recursion ends when the extracted value is
684  // a floating point number.
685  return NumberType<T>::value(ExtractData<F>::value(f));
686  }
687 
694  template <typename F>
695  static T
696  value(const F &f,
697  typename std::enable_if<is_ad_number<F>::value &&
698  is_ad_number<T>::value>::type * = nullptr)
699  {
700  return T(f);
701  }
702  };
703 
704  template <typename T>
705  struct NumberType<std::complex<T>>
706  {
710  template <typename F>
711  static auto
712  value(
713  const F &f,
714  typename std::enable_if<!is_ad_number<F>::value>::type * = nullptr)
715  -> decltype(::internal::NumberType<std::complex<T>>::value(f))
716  {
717  // We call the other function defined in the numbers
718  // header to take care of all of the usual cases.
719  return ::internal::NumberType<std::complex<T>>::value(f);
720  }
721 
722 
727  template <typename F>
728  static std::complex<T>
729  value(const F &f,
730  typename std::enable_if<is_ad_number<F>::value &&
731  std::is_floating_point<T>::value>::type
732  * = nullptr)
733  {
734  // We recursively call this function in case the AD number is a
735  // nested one. The recursion ends when the extracted value is
736  // a floating point number.
737  return std::complex<T>(
738  NumberType<T>::value(ExtractData<F>::value(f)));
739  }
740 
741  template <typename F>
742  static std::complex<T>
743  value(const std::complex<F> &f)
744  {
745  // Deal with the two parts of the input complex
746  // number individually.
747  return std::complex<T>(NumberType<T>::value(f.real()),
748  NumberType<T>::value(f.imag()));
749  }
750  };
751 
752  } // namespace internal
753 
754 
755 
776  template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
777  struct NumberTraits<
778  ScalarType,
779  ADNumberTypeCode,
780  typename std::enable_if<
781  std::is_floating_point<ScalarType>::value ||
782  (boost::is_complex<ScalarType>::value &&
783  std::is_floating_point<typename internal::RemoveComplexWrapper<
784  ScalarType>::type>::value)>::type>
785  {
789  static constexpr enum NumberTypes type_code = ADNumberTypeCode;
790 
791  // The clang compiler does not seem to like these
792  // variables being defined as constant expressions
793  // (the tests <adolc|sacado>/ad_number_traits_02 will
794  // fail with linking errors). However, GCC complains
795  // about the use of non-constant expressions in
796  // std::conditional.
797 # ifdef __clang__
798 
803  static const bool is_taped;
804 
805 
810  static const bool is_tapeless;
811 
812 
817  static const bool is_real_valued;
818 
819 
824  static const bool is_complex_valued;
825 
826 
831  static const unsigned int n_supported_derivative_levels;
832 
833 # else
834 
839  static constexpr bool is_taped = internal::ADNumberInfoFromEnum<
841  ADNumberTypeCode>::is_taped;
842 
843 
848  static constexpr bool is_tapeless =
850 
851 
856  static constexpr bool is_real_valued =
857  (!boost::is_complex<ScalarType>::value);
858 
859 
864  static constexpr bool is_complex_valued =
866 
867 
872  static constexpr unsigned int n_supported_derivative_levels =
874  typename internal::RemoveComplexWrapper<ScalarType>::type,
875  ADNumberTypeCode>::n_supported_derivative_levels;
876 
877 # endif
878 
879 
884  using scalar_type = ScalarType;
885 
886 
890  using real_type = typename internal::ADNumberInfoFromEnum<
891  typename internal::RemoveComplexWrapper<ScalarType>::type,
892  ADNumberTypeCode>::real_type;
893 
894 
898  using complex_type = std::complex<real_type>;
899 
900 
904  using ad_type = typename std::
905  conditional<is_real_valued, real_type, complex_type>::type;
906 
910  using derivative_type = typename std::conditional<
911  is_real_valued,
913  typename internal::RemoveComplexWrapper<ScalarType>::type,
914  ADNumberTypeCode>::derivative_type,
915  std::complex<typename internal::ADNumberInfoFromEnum<
916  typename internal::RemoveComplexWrapper<ScalarType>::type,
917  ADNumberTypeCode>::derivative_type>>::type;
918 
919 
923  static scalar_type get_scalar_value(const ad_type &x)
924  {
925  // Some tricky conversion cases to consider here:
926  // - Nested AD numbers
927  // - std::complex<double> --> std::complex<float>
928  // e.g. when ScalarType = float and ADNumberTypeCode = adolc_taped
929  // Therefore, we use the internal casting mechanism
930  // provided by the internal::NumberType struct.
933  }
934 
935 
939  static derivative_type get_directional_derivative(
940  const ad_type &x, const unsigned int direction)
941  {
943  x, direction);
944  }
945 
946 
951  static unsigned int n_directional_derivatives(const ad_type &x)
952  {
954  }
955 
956 
957  static_assert((is_real_valued == true ?
958  std::is_same<ad_type, real_type>::value :
959  std::is_same<ad_type, complex_type>::value),
960  "Incorrect template type selected for ad_type");
961 
962  static_assert((is_complex_valued == true ?
963  boost::is_complex<scalar_type>::value :
964  true),
965  "Expected a complex float_type");
966 
967  static_assert((is_complex_valued == true ?
968  boost::is_complex<ad_type>::value :
969  true),
970  "Expected a complex ad_type");
971  };
972 
973 # ifdef __clang__
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_taped =
985  typename internal::RemoveComplexWrapper<ScalarType>::type,
986  ADNumberTypeCode>::is_taped;
987 
988 
989  template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
990  const bool NumberTraits<
991  ScalarType,
992  ADNumberTypeCode,
993  typename std::enable_if<
994  std::is_floating_point<ScalarType>::value ||
995  (boost::is_complex<ScalarType>::value &&
996  std::is_floating_point<typename internal::RemoveComplexWrapper<
997  ScalarType>::type>::value)>::type>::is_tapeless =
999 
1000 
1001  template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
1002  const bool NumberTraits<
1003  ScalarType,
1004  ADNumberTypeCode,
1005  typename std::enable_if<
1006  std::is_floating_point<ScalarType>::value ||
1007  (boost::is_complex<ScalarType>::value &&
1008  std::is_floating_point<typename internal::RemoveComplexWrapper<
1009  ScalarType>::type>::value)>::type>::is_real_valued =
1010  (!boost::is_complex<ScalarType>::value);
1011 
1012 
1013  template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
1014  const bool NumberTraits<
1015  ScalarType,
1016  ADNumberTypeCode,
1017  typename std::enable_if<
1018  std::is_floating_point<ScalarType>::value ||
1019  (boost::is_complex<ScalarType>::value &&
1020  std::is_floating_point<typename internal::RemoveComplexWrapper<
1021  ScalarType>::type>::value)>::type>::is_complex_valued =
1023 
1024 
1025  template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
1026  const unsigned int 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>::n_supported_derivative_levels =
1035  typename internal::RemoveComplexWrapper<ScalarType>::type,
1036  ADNumberTypeCode>::n_supported_derivative_levels;
1037 
1038 # else
1039 
1040  template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
1041  constexpr bool NumberTraits<
1042  ScalarType,
1043  ADNumberTypeCode,
1044  typename std::enable_if<
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)>::type>::is_taped;
1049 
1050 
1051  template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
1052  constexpr bool NumberTraits<
1053  ScalarType,
1054  ADNumberTypeCode,
1055  typename std::enable_if<
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)>::type>::is_tapeless;
1060 
1061 
1062  template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
1063  constexpr bool NumberTraits<
1064  ScalarType,
1065  ADNumberTypeCode,
1066  typename std::enable_if<
1067  std::is_floating_point<ScalarType>::value ||
1068  (boost::is_complex<ScalarType>::value &&
1069  std::is_floating_point<typename internal::RemoveComplexWrapper<
1070  ScalarType>::type>::value)>::type>::is_real_valued;
1071 
1072 
1073  template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
1074  constexpr bool NumberTraits<
1075  ScalarType,
1076  ADNumberTypeCode,
1077  typename std::enable_if<
1078  std::is_floating_point<ScalarType>::value ||
1079  (boost::is_complex<ScalarType>::value &&
1080  std::is_floating_point<typename internal::RemoveComplexWrapper<
1081  ScalarType>::type>::value)>::type>::is_complex_valued;
1082 
1083 
1084  template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
1085  constexpr unsigned int NumberTraits<
1086  ScalarType,
1087  ADNumberTypeCode,
1088  typename std::enable_if<
1089  std::is_floating_point<ScalarType>::value ||
1090  (boost::is_complex<ScalarType>::value &&
1091  std::is_floating_point<typename internal::RemoveComplexWrapper<
1092  ScalarType>::type>::value)>::type>::n_supported_derivative_levels;
1093 
1094 # endif
1095 
1096 
1097 
1107  template <typename ScalarType>
1108  struct NumberTraits<
1109  ScalarType,
1110  NumberTypes::none,
1111  typename std::enable_if<
1112  std::is_floating_point<ScalarType>::value ||
1113  (boost::is_complex<ScalarType>::value &&
1114  std::is_floating_point<typename internal::RemoveComplexWrapper<
1115  ScalarType>::type>::value)>::type>
1116  {
1120  static constexpr enum NumberTypes type_code = NumberTypes::none;
1121 
1122  // The clang compiler does not seem to like these
1123  // variables being defined as constant expressions
1124  // (the tests <adolc|sacado>/ad_number_traits_02 will
1125  // fail with linking errors). However, GCC complains
1126  // about the use of non-constant expressions in
1127  // std::conditional.
1128 # ifdef __clang__
1129 
1134  static const bool is_taped;
1135 
1136 
1141  static const bool is_tapeless;
1142 
1143 
1148  static const bool is_real_valued;
1149 
1150 
1155  static const bool is_complex_valued;
1156 
1157 
1162  static const unsigned int n_supported_derivative_levels;
1163 
1164 # else
1165 
1170  static constexpr bool is_taped = false;
1171 
1172 
1177  static constexpr bool is_tapeless = false;
1178 
1179 
1184  static constexpr bool is_real_valued =
1185  (!boost::is_complex<ScalarType>::value);
1186 
1187 
1192  static constexpr bool is_complex_valued = !is_real_valued;
1193 
1194 
1199  static constexpr unsigned int n_supported_derivative_levels = 0;
1200 
1201 # endif
1202 
1203 
1208  using scalar_type = ScalarType;
1209 
1210 
1214  using real_type =
1215  typename ::numbers::NumberTraits<scalar_type>::real_type;
1216 
1217 
1221  using complex_type = std::complex<real_type>;
1222 
1223 
1227  using ad_type = ScalarType;
1228 
1232  using derivative_type = ScalarType;
1233 
1234 
1238  static scalar_type
1239  get_scalar_value(const ad_type &x)
1240  {
1241  return x;
1242  }
1243 
1244 
1248  static derivative_type
1249  get_directional_derivative(const ad_type &, const unsigned int)
1250  {
1251  Assert(
1252  false,
1253  ExcMessage(
1254  "Floating point/arithmetic numbers have no directional derivatives."));
1255  return derivative_type();
1256  }
1257 
1258 
1263  static unsigned int
1264  n_directional_derivatives(const ad_type &)
1265  {
1266  Assert(
1267  false,
1268  ExcMessage(
1269  "Floating point/arithmetic numbers have no directional derivatives."));
1270  return 0;
1271  }
1272  };
1273 
1274 # ifdef __clang__
1275 
1276  template <typename ScalarType>
1277  const bool NumberTraits<
1278  ScalarType,
1280  typename std::enable_if<
1281  std::is_floating_point<ScalarType>::value ||
1282  (boost::is_complex<ScalarType>::value &&
1283  std::is_floating_point<typename internal::RemoveComplexWrapper<
1284  ScalarType>::type>::value)>::type>::is_taped = false;
1285 
1286 
1287  template <typename ScalarType>
1288  const bool NumberTraits<
1289  ScalarType,
1291  typename std::enable_if<
1292  std::is_floating_point<ScalarType>::value ||
1293  (boost::is_complex<ScalarType>::value &&
1294  std::is_floating_point<typename internal::RemoveComplexWrapper<
1295  ScalarType>::type>::value)>::type>::is_tapeless = false;
1296 
1297 
1298  template <typename ScalarType>
1299  const bool NumberTraits<
1300  ScalarType,
1302  typename std::enable_if<
1303  std::is_floating_point<ScalarType>::value ||
1304  (boost::is_complex<ScalarType>::value &&
1305  std::is_floating_point<typename internal::RemoveComplexWrapper<
1306  ScalarType>::type>::value)>::type>::is_real_valued =
1307  (!boost::is_complex<ScalarType>::value);
1308 
1309 
1310  template <typename ScalarType>
1311  const bool NumberTraits<
1312  ScalarType,
1314  typename std::enable_if<
1315  std::is_floating_point<ScalarType>::value ||
1316  (boost::is_complex<ScalarType>::value &&
1317  std::is_floating_point<typename internal::RemoveComplexWrapper<
1318  ScalarType>::type>::value)>::type>::is_complex_valued =
1320 
1321 
1322  template <typename ScalarType>
1323  const unsigned int NumberTraits<
1324  ScalarType,
1326  typename std::enable_if<
1327  std::is_floating_point<ScalarType>::value ||
1328  (boost::is_complex<ScalarType>::value &&
1329  std::is_floating_point<typename internal::RemoveComplexWrapper<
1330  ScalarType>::type>::value)>::type>::n_supported_derivative_levels =
1331  0;
1332 
1333 # else
1334 
1335  template <typename ScalarType>
1336  constexpr bool NumberTraits<
1337  ScalarType,
1339  typename std::enable_if<
1340  std::is_floating_point<ScalarType>::value ||
1341  (boost::is_complex<ScalarType>::value &&
1342  std::is_floating_point<typename internal::RemoveComplexWrapper<
1343  ScalarType>::type>::value)>::type>::is_taped;
1344 
1345 
1346  template <typename ScalarType>
1347  constexpr bool NumberTraits<
1348  ScalarType,
1350  typename std::enable_if<
1351  std::is_floating_point<ScalarType>::value ||
1352  (boost::is_complex<ScalarType>::value &&
1353  std::is_floating_point<typename internal::RemoveComplexWrapper<
1354  ScalarType>::type>::value)>::type>::is_tapeless;
1355 
1356 
1357  template <typename ScalarType>
1358  constexpr bool NumberTraits<
1359  ScalarType,
1361  typename std::enable_if<
1362  std::is_floating_point<ScalarType>::value ||
1363  (boost::is_complex<ScalarType>::value &&
1364  std::is_floating_point<typename internal::RemoveComplexWrapper<
1365  ScalarType>::type>::value)>::type>::is_real_valued;
1366 
1367 
1368  template <typename ScalarType>
1369  constexpr bool NumberTraits<
1370  ScalarType,
1372  typename std::enable_if<
1373  std::is_floating_point<ScalarType>::value ||
1374  (boost::is_complex<ScalarType>::value &&
1375  std::is_floating_point<typename internal::RemoveComplexWrapper<
1376  ScalarType>::type>::value)>::type>::is_complex_valued;
1377 
1378 
1379  template <typename ScalarType>
1380  constexpr unsigned int NumberTraits<
1381  ScalarType,
1383  typename std::enable_if<
1384  std::is_floating_point<ScalarType>::value ||
1385  (boost::is_complex<ScalarType>::value &&
1386  std::is_floating_point<typename internal::RemoveComplexWrapper<
1387  ScalarType>::type>::value)>::type>::n_supported_derivative_levels;
1388 
1389 # endif
1390 
1391 
1410  template <typename ScalarType>
1411  struct ADNumberTraits<
1412  ScalarType,
1413  typename std::enable_if<std::is_floating_point<ScalarType>::value>::type>
1414  : NumberTraits<ScalarType, NumberTypes::none>
1415  {};
1416 
1420  template <typename ComplexScalarType>
1421  struct ADNumberTraits<
1422  ComplexScalarType,
1423  typename std::enable_if<
1424  boost::is_complex<ComplexScalarType>::value &&
1425  std::is_floating_point<typename ComplexScalarType::value_type>::value>::
1426  type> : NumberTraits<ComplexScalarType, NumberTypes::none>
1427  {};
1428 
1429  } // namespace AD
1430 } // namespace Differentiation
1431 
1432 #endif // DOXYGEN
1433 
1434 
1435 namespace numbers
1436 {
1437  template <typename ADNumberType>
1438  bool
1439  is_nan(const typename std::enable_if<
1441  ADNumberType>::type &x)
1442  {
1443  return is_nan(
1445  }
1446 
1447 } // namespace numbers
1448 
1449 
1450 DEAL_II_NAMESPACE_CLOSE
1451 
1452 #endif
STL namespace.
#define AssertThrow(cond, exc)
Definition: exceptions.h:1523
static ::ExceptionBase & ExcMessage(std::string arg1)
#define Assert(cond, exc)
Definition: exceptions.h:1411