Reference documentation for deal.II version GIT 5983d193e2 2023-05-27 16:50:02+00:00
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
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  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  {
370  AssertThrow(
371  false,
372  ExcMessage(
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  {
395  AssertThrow(
396  false,
397  ExcMessage(
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  {
409  AssertThrow(
410  false,
411  ExcMessage(
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)
633  -> decltype(::internal::NumberType<T>::value(f))
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,
1077  NumberTypes::none,
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:474
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:475
#define Assert(cond, exc)
Definition: exceptions.h:1614
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
Definition: exceptions.h:1703
static const char T
Tensor< 2, dim, Number > F(const Tensor< 2, dim, Number > &Grad_u)
static constexpr DEAL_II_HOST_DEVICE_ALWAYS_INLINE const T & value(const T &t)
Definition: numbers.h:702