Reference documentation for deal.II version Git 4abc4a1666 2020-07-04 19:58:34 +0200
\(\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 
22 #include <deal.II/base/numbers.h>
23 
25 
26 #include <boost/type_traits.hpp>
27 
28 #include <complex>
29 #include <type_traits>
30 
32 
33 namespace Differentiation
34 {
35  namespace AD
36  {
48  template <typename ScalarType,
49  enum NumberTypes ADNumberTypeCode,
50  typename T = void>
51  struct NumberTraits;
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>
176  struct ExtractData;
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 
282 namespace 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  {
371  AssertThrow(
372  false,
373  ExcMessage(
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  {
397  AssertThrow(
398  false,
399  ExcMessage(
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  {
411  AssertThrow(
412  false,
413  ExcMessage(
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
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>
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>
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<
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<
613  directional_derivative(const std::complex<ADNumberType> &x,
614  const unsigned int direction)
615  {
616  return std::complex<
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<
815  ADNumberTypeCode>::is_taped;
816 
817 
822  static constexpr bool is_tapeless =
824 
825 
830  static constexpr bool is_real_valued =
831  (!boost::is_complex<ScalarType>::value);
832 
833 
838  static constexpr bool is_complex_valued =
840 
841 
846  static constexpr unsigned int n_supported_derivative_levels =
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,
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.
907  }
908 
909 
913  static derivative_type get_directional_derivative(
914  const ad_type &x, const unsigned int direction)
915  {
917  x, direction);
918  }
919 
920 
925  static unsigned int n_directional_derivatives(const ad_type &x)
926  {
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 =
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 =
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 =
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 =
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,
1084  NumberTypes::none,
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 =
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
static constexpr const T & value(const T &t)
Definition: numbers.h:693
STL namespace.
#define AssertThrow(cond, exc)
Definition: exceptions.h:1513
Tensor< 2, dim, Number > F(const Tensor< 2, dim, Number > &Grad_u)
static ::ExceptionBase & ExcMessage(std::string arg1)
static const char T
#define Assert(cond, exc)
Definition: exceptions.h:1403
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:363
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:362