Reference documentation for deal.II version GIT 9042b9283b 2023-12-02 14: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 - 2023 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE.md at
12 // the top level directory of deal.II.
13 //
14 // ---------------------------------------------------------------------
15 
16 #ifndef dealii_differentiation_ad_ad_number_traits_h
17 #define dealii_differentiation_ad_ad_number_traits_h
18 
19 #include <deal.II/base/config.h>
20 
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_t<
313  std::is_floating_point_v<typename ADNumberTrait::real_type>,
314  std::false_type,
315  std::true_type>
316  {};
317 
318 
323  template <typename ScalarType>
324  struct ADNumberInfoFromEnum<
325  ScalarType,
327  std::enable_if_t<std::is_floating_point_v<ScalarType>>>
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<ScalarType,
343  std::enable_if_t<std::is_floating_point_v<ScalarType>>>
344  {
352  template <typename ADNumberType>
353  static void
354  independent_variable(const ScalarType &in,
355  const unsigned int,
356  const unsigned int,
357  ADNumberType &out)
358  {
359  out = in;
360  }
361 
362  /*
363  * Initialize the state of a dependent variable.
364  */
365  template <typename ADNumberType>
366  static void
367  dependent_variable(ADNumberType &, const ScalarType &)
368  {
369  AssertThrow(
370  false,
371  ExcMessage(
372  "Floating point numbers cannot be marked as dependent variables."));
373  }
374  };
375 
376 
380  template <typename ADNumberType>
381  struct Marking<ADNumberType,
382  std::enable_if_t<boost::is_complex<ADNumberType>::value>>
383  {
384  /*
385  * Initialize the state of an independent variable.
386  */
387  template <typename ScalarType>
388  static void
389  independent_variable(const ScalarType &in,
390  const unsigned int,
391  const unsigned int,
392  ADNumberType &out)
393  {
394  AssertThrow(
395  false,
396  ExcMessage(
397  "Marking for complex numbers has not yet been implemented."));
398  out = in;
399  }
400 
401  /*
402  * Initialize the state of a dependent variable.
403  */
404  template <typename ScalarType>
405  static void
406  dependent_variable(ADNumberType &, const ScalarType &)
407  {
408  AssertThrow(
409  false,
410  ExcMessage(
411  "Marking for complex numbers has not yet been implemented."));
412  }
413  };
414 
415  } // namespace internal
416 
417 
418  template <typename NumberType, typename>
419  struct is_taped_ad_number : std::false_type
420  {};
421 
422 
423  template <typename NumberType, typename>
424  struct is_tapeless_ad_number : std::false_type
425  {};
426 
427 
428  template <typename NumberType, typename>
429  struct is_real_valued_ad_number : std::false_type
430  {};
431 
432 
433  template <typename NumberType, typename>
434  struct is_complex_valued_ad_number : std::false_type
435  {};
436 
437 
443  template <typename NumberType>
444  struct is_ad_number
445  : internal::HasRequiredADInfo<ADNumberTraits<std::decay_t<NumberType>>>
446  {};
447 
448 
453  template <typename NumberType>
454  struct is_taped_ad_number<
455  NumberType,
456  std::enable_if_t<ADNumberTraits<std::decay_t<NumberType>>::is_taped>>
457  : std::true_type
458  {};
459 
460 
465  template <typename NumberType>
466  struct is_tapeless_ad_number<
467  NumberType,
468  std::enable_if_t<ADNumberTraits<std::decay_t<NumberType>>::is_tapeless>>
469  : std::true_type
470  {};
471 
472 
478  template <typename NumberType>
479  struct is_real_valued_ad_number<
480  NumberType,
481  std::enable_if_t<
482  ADNumberTraits<std::decay_t<NumberType>>::is_real_valued>>
483  : std::true_type
484  {};
485 
486 
492  template <typename NumberType>
493  struct is_complex_valued_ad_number<
494  NumberType,
495  std::enable_if_t<
496  ADNumberTraits<std::decay_t<NumberType>>::is_complex_valued>>
497  : std::true_type
498  {};
499 
500 
501  namespace internal
502  {
507  template <typename Number>
508  struct RemoveComplexWrapper
509  {
510  using type = Number;
511  };
512 
513 
519  template <typename Number>
520  struct RemoveComplexWrapper<std::complex<Number>>
521  {
522  using type = typename RemoveComplexWrapper<Number>::type;
523  };
524 
525 
531  template <typename NumberType>
532  struct ExtractData<NumberType,
533  std::enable_if_t<std::is_floating_point_v<NumberType>>>
534  {
538  static const NumberType &
539  value(const NumberType &x)
540  {
541  return x;
542  }
543 
544 
548  static unsigned int
549  n_directional_derivatives(const NumberType &)
550  {
551  return 0;
552  }
553 
554 
558  static NumberType
559  directional_derivative(const NumberType &, const unsigned int)
560  {
561  return 0.0;
562  }
563  };
564 
565 
566 
571  template <typename ADNumberType>
572  struct ExtractData<std::complex<ADNumberType>>
573  {
575  "Expected an auto-differentiable number.");
576 
577 
581  static std::complex<typename ADNumberTraits<ADNumberType>::scalar_type>
582  value(const std::complex<ADNumberType> &x)
583  {
584  return std::complex<
585  typename ADNumberTraits<ADNumberType>::scalar_type>(
586  ExtractData<ADNumberType>::value(x.real()),
587  ExtractData<ADNumberType>::value(x.imag()));
588  }
589 
590 
594  static unsigned int
595  n_directional_derivatives(const std::complex<ADNumberType> &x)
596  {
597  return ExtractData<ADNumberType>::n_directional_derivatives(x.real());
598  }
599 
600 
604  static std::complex<
605  typename ADNumberTraits<ADNumberType>::derivative_type>
606  directional_derivative(const std::complex<ADNumberType> &x,
607  const unsigned int direction)
608  {
609  return std::complex<
610  typename ADNumberTraits<ADNumberType>::derivative_type>(
611  ExtractData<ADNumberType>::directional_derivative(x.real(),
612  direction),
613  ExtractData<ADNumberType>::directional_derivative(x.imag(),
614  direction));
615  }
616  };
617 
618 
619  template <typename T>
620  struct NumberType
621  {
625  template <typename F>
626  static auto
627  value(const F &f, std::enable_if_t<!is_ad_number<F>::value> * = nullptr)
628  -> decltype(::internal::NumberType<T>::value(f))
629  {
630  // We call the other function defined in the numbers
631  // header to take care of all of the usual cases.
632  return ::internal::NumberType<T>::value(f);
633  }
634 
641  template <typename F>
642  static T
643  value(const F &f,
644  std::enable_if_t<is_ad_number<F>::value &&
645  std::is_floating_point_v<T>> * = nullptr)
646  {
647  // We recursively call this function in case the AD number is a
648  // nested one. The recursion ends when the extracted value is
649  // a floating point number.
650  return NumberType<T>::value(ExtractData<F>::value(f));
651  }
652 
659  template <typename F>
660  static T
661  value(const F &f,
662  std::enable_if_t<is_ad_number<F>::value && is_ad_number<T>::value>
663  * = nullptr)
664  {
665  return T(f);
666  }
667  };
668 
669  template <typename T>
670  struct NumberType<std::complex<T>>
671  {
675  template <typename F>
676  static auto
677  value(const F &f, std::enable_if_t<!is_ad_number<F>::value> * = nullptr)
678  -> decltype(::internal::NumberType<std::complex<T>>::value(f))
679  {
680  // We call the other function defined in the numbers
681  // header to take care of all of the usual cases.
682  return ::internal::NumberType<std::complex<T>>::value(f);
683  }
684 
685 
690  template <typename F>
691  static std::complex<T>
692  value(const F &f,
693  std::enable_if_t<is_ad_number<F>::value &&
694  std::is_floating_point_v<T>> * = nullptr)
695  {
696  // We recursively call this function in case the AD number is a
697  // nested one. The recursion ends when the extracted value is
698  // a floating point number.
699  return std::complex<T>(
700  NumberType<T>::value(ExtractData<F>::value(f)));
701  }
702 
703  template <typename F>
704  static std::complex<T>
705  value(const std::complex<F> &f)
706  {
707  // Deal with the two parts of the input complex
708  // number individually.
709  return std::complex<T>(NumberType<T>::value(f.real()),
710  NumberType<T>::value(f.imag()));
711  }
712  };
713 
714  } // namespace internal
715 
716 
717 
738  template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
739  struct NumberTraits<
740  ScalarType,
741  ADNumberTypeCode,
742  std::enable_if_t<
743  std::is_floating_point_v<ScalarType> ||
744  (boost::is_complex<ScalarType>::value &&
745  std::is_floating_point<
746  typename internal::RemoveComplexWrapper<ScalarType>::type>::value)>>
747  {
751  static constexpr enum NumberTypes type_code = ADNumberTypeCode;
752 
753  // The clang compiler does not seem to like these
754  // variables being defined as constant expressions
755  // (the tests <adolc|sacado>/ad_number_traits_02 will
756  // fail with linking errors). However, GCC complains
757  // about the use of non-constant expressions in
758  // std::conditional.
759 # ifdef __clang__
760 
765  static const bool is_taped;
766 
767 
772  static const bool is_tapeless;
773 
774 
779  static const bool is_real_valued;
780 
781 
786  static const bool is_complex_valued;
787 
788 
793  static const unsigned int n_supported_derivative_levels;
794 
795 # else
796 
801  static constexpr bool is_taped = internal::ADNumberInfoFromEnum<
802  typename internal::RemoveComplexWrapper<ScalarType>::type,
803  ADNumberTypeCode>::is_taped;
804 
805 
810  static constexpr bool is_tapeless =
811  !(NumberTraits<ScalarType, ADNumberTypeCode>::is_taped);
812 
813 
818  static constexpr bool is_real_valued =
819  (!boost::is_complex<ScalarType>::value);
820 
821 
826  static constexpr bool is_complex_valued =
827  !(NumberTraits<ScalarType, ADNumberTypeCode>::is_real_valued);
828 
829 
834  static constexpr unsigned int n_supported_derivative_levels =
835  internal::ADNumberInfoFromEnum<
836  typename internal::RemoveComplexWrapper<ScalarType>::type,
837  ADNumberTypeCode>::n_supported_derivative_levels;
838 
839 # endif
840 
841 
846  using scalar_type = ScalarType;
847 
848 
852  using real_type = typename internal::ADNumberInfoFromEnum<
853  typename internal::RemoveComplexWrapper<ScalarType>::type,
854  ADNumberTypeCode>::real_type;
855 
856 
860  using complex_type = std::complex<real_type>;
861 
862 
866  using ad_type = typename std::
867  conditional<is_real_valued, real_type, complex_type>::type;
868 
872  using derivative_type = std::conditional_t<
873  is_real_valued,
874  typename internal::ADNumberInfoFromEnum<
875  typename internal::RemoveComplexWrapper<ScalarType>::type,
876  ADNumberTypeCode>::derivative_type,
877  std::complex<typename internal::ADNumberInfoFromEnum<
878  typename internal::RemoveComplexWrapper<ScalarType>::type,
879  ADNumberTypeCode>::derivative_type>>;
880 
881 
885  static scalar_type get_scalar_value(const ad_type &x)
886  {
887  // Some tricky conversion cases to consider here:
888  // - Nested AD numbers
889  // - std::complex<double> --> std::complex<float>
890  // e.g. when ScalarType = float and ADNumberTypeCode = adolc_taped
891  // Therefore, we use the internal casting mechanism
892  // provided by the internal::NumberType struct.
894  internal::ExtractData<ad_type>::value(x));
895  }
896 
897 
901  static derivative_type get_directional_derivative(
902  const ad_type &x, const unsigned int direction)
903  {
904  return internal::ExtractData<ad_type>::directional_derivative(
905  x, direction);
906  }
907 
908 
913  static unsigned int n_directional_derivatives(const ad_type &x)
914  {
915  return internal::ExtractData<ad_type>::n_directional_derivatives(x);
916  }
917 
918 
919  static_assert((is_real_valued == true ?
920  std::is_same_v<ad_type, real_type> :
921  std::is_same_v<ad_type, complex_type>),
922  "Incorrect template type selected for ad_type");
923 
924  static_assert((is_complex_valued == true ?
925  boost::is_complex<scalar_type>::value :
926  true),
927  "Expected a complex float_type");
928 
929  static_assert((is_complex_valued == true ?
930  boost::is_complex<ad_type>::value :
931  true),
932  "Expected a complex ad_type");
933  };
934 
935 # ifdef __clang__
936 
937  template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
938  const bool NumberTraits<
939  ScalarType,
940  ADNumberTypeCode,
941  std::enable_if_t<
942  std::is_floating_point_v<ScalarType> ||
943  (boost::is_complex<ScalarType>::value &&
944  std::is_floating_point<typename internal::RemoveComplexWrapper<
945  ScalarType>::type>::value)>>::is_taped =
946  internal::ADNumberInfoFromEnum<
947  typename internal::RemoveComplexWrapper<ScalarType>::type,
948  ADNumberTypeCode>::is_taped;
949 
950 
951  template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
952  const bool NumberTraits<
953  ScalarType,
954  ADNumberTypeCode,
955  std::enable_if_t<
956  std::is_floating_point_v<ScalarType> ||
957  (boost::is_complex<ScalarType>::value &&
958  std::is_floating_point<typename internal::RemoveComplexWrapper<
959  ScalarType>::type>::value)>>::is_tapeless =
960  !(NumberTraits<ScalarType, ADNumberTypeCode>::is_taped);
961 
962 
963  template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
964  const bool NumberTraits<
965  ScalarType,
966  ADNumberTypeCode,
967  std::enable_if_t<
968  std::is_floating_point_v<ScalarType> ||
969  (boost::is_complex<ScalarType>::value &&
970  std::is_floating_point<typename internal::RemoveComplexWrapper<
971  ScalarType>::type>::value)>>::is_real_valued =
972  (!boost::is_complex<ScalarType>::value);
973 
974 
975  template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
976  const bool NumberTraits<
977  ScalarType,
978  ADNumberTypeCode,
979  std::enable_if_t<
980  std::is_floating_point_v<ScalarType> ||
981  (boost::is_complex<ScalarType>::value &&
982  std::is_floating_point<typename internal::RemoveComplexWrapper<
983  ScalarType>::type>::value)>>::is_complex_valued =
984  !(NumberTraits<ScalarType, ADNumberTypeCode>::is_real_valued);
985 
986 
987  template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
988  const unsigned int NumberTraits<
989  ScalarType,
990  ADNumberTypeCode,
991  std::enable_if_t<
992  std::is_floating_point_v<ScalarType> ||
993  (boost::is_complex<ScalarType>::value &&
994  std::is_floating_point<typename internal::RemoveComplexWrapper<
995  ScalarType>::type>::value)>>::n_supported_derivative_levels =
996  internal::ADNumberInfoFromEnum<
997  typename internal::RemoveComplexWrapper<ScalarType>::type,
998  ADNumberTypeCode>::n_supported_derivative_levels;
999 
1000 # else
1001 
1002  template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
1003  constexpr bool NumberTraits<
1004  ScalarType,
1005  ADNumberTypeCode,
1006  std::enable_if_t<
1007  std::is_floating_point_v<ScalarType> ||
1008  (boost::is_complex<ScalarType>::value &&
1009  std::is_floating_point<typename internal::RemoveComplexWrapper<
1010  ScalarType>::type>::value)>>::is_taped;
1011 
1012 
1013  template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
1014  constexpr bool NumberTraits<
1015  ScalarType,
1016  ADNumberTypeCode,
1017  std::enable_if_t<
1018  std::is_floating_point_v<ScalarType> ||
1019  (boost::is_complex<ScalarType>::value &&
1020  std::is_floating_point<typename internal::RemoveComplexWrapper<
1021  ScalarType>::type>::value)>>::is_tapeless;
1022 
1023 
1024  template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
1025  constexpr bool NumberTraits<
1026  ScalarType,
1027  ADNumberTypeCode,
1028  std::enable_if_t<
1029  std::is_floating_point_v<ScalarType> ||
1030  (boost::is_complex<ScalarType>::value &&
1031  std::is_floating_point<typename internal::RemoveComplexWrapper<
1032  ScalarType>::type>::value)>>::is_real_valued;
1033 
1034 
1035  template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
1036  constexpr bool NumberTraits<
1037  ScalarType,
1038  ADNumberTypeCode,
1039  std::enable_if_t<
1040  std::is_floating_point_v<ScalarType> ||
1041  (boost::is_complex<ScalarType>::value &&
1042  std::is_floating_point<typename internal::RemoveComplexWrapper<
1043  ScalarType>::type>::value)>>::is_complex_valued;
1044 
1045 
1046  template <typename ScalarType, enum NumberTypes ADNumberTypeCode>
1047  constexpr unsigned int NumberTraits<
1048  ScalarType,
1049  ADNumberTypeCode,
1050  std::enable_if_t<
1051  std::is_floating_point_v<ScalarType> ||
1052  (boost::is_complex<ScalarType>::value &&
1053  std::is_floating_point<typename internal::RemoveComplexWrapper<
1054  ScalarType>::type>::value)>>::n_supported_derivative_levels;
1055 
1056 # endif
1057 
1058 
1059 
1069  template <typename ScalarType>
1070  struct NumberTraits<
1071  ScalarType,
1072  NumberTypes::none,
1073  std::enable_if_t<
1074  std::is_floating_point_v<ScalarType> ||
1075  (boost::is_complex<ScalarType>::value &&
1076  std::is_floating_point<
1077  typename internal::RemoveComplexWrapper<ScalarType>::type>::value)>>
1078  {
1082  static constexpr enum NumberTypes type_code = NumberTypes::none;
1083 
1084  // The clang compiler does not seem to like these
1085  // variables being defined as constant expressions
1086  // (the tests <adolc|sacado>/ad_number_traits_02 will
1087  // fail with linking errors). However, GCC complains
1088  // about the use of non-constant expressions in
1089  // std::conditional.
1090 # ifdef __clang__
1091 
1096  static const bool is_taped;
1097 
1098 
1103  static const bool is_tapeless;
1104 
1105 
1110  static const bool is_real_valued;
1111 
1112 
1117  static const bool is_complex_valued;
1118 
1119 
1124  static const unsigned int n_supported_derivative_levels;
1125 
1126 # else
1127 
1132  static constexpr bool is_taped = false;
1133 
1134 
1139  static constexpr bool is_tapeless = false;
1140 
1141 
1146  static constexpr bool is_real_valued =
1147  (!boost::is_complex<ScalarType>::value);
1148 
1149 
1154  static constexpr bool is_complex_valued = !is_real_valued;
1155 
1156 
1161  static constexpr unsigned int n_supported_derivative_levels = 0;
1162 
1163 # endif
1164 
1165 
1170  using scalar_type = ScalarType;
1171 
1172 
1176  using real_type =
1177  typename ::numbers::NumberTraits<scalar_type>::real_type;
1178 
1179 
1183  using complex_type = std::complex<real_type>;
1184 
1185 
1189  using ad_type = ScalarType;
1190 
1194  using derivative_type = ScalarType;
1195 
1196 
1200  static scalar_type
1201  get_scalar_value(const ad_type &x)
1202  {
1203  return x;
1204  }
1205 
1206 
1210  static derivative_type
1211  get_directional_derivative(const ad_type &, const unsigned int)
1212  {
1213  Assert(
1214  false,
1215  ExcMessage(
1216  "Floating point/arithmetic numbers have no directional derivatives."));
1217  return derivative_type();
1218  }
1219 
1220 
1225  static unsigned int
1226  n_directional_derivatives(const ad_type &)
1227  {
1228  Assert(
1229  false,
1230  ExcMessage(
1231  "Floating point/arithmetic numbers have no directional derivatives."));
1232  return 0;
1233  }
1234  };
1235 
1236 # ifdef __clang__
1237 
1238  template <typename ScalarType>
1239  const bool NumberTraits<
1240  ScalarType,
1242  std::enable_if_t<
1243  std::is_floating_point_v<ScalarType> ||
1244  (boost::is_complex<ScalarType>::value &&
1245  std::is_floating_point<typename internal::RemoveComplexWrapper<
1246  ScalarType>::type>::value)>>::is_taped = false;
1247 
1248 
1249  template <typename ScalarType>
1250  const bool NumberTraits<
1251  ScalarType,
1253  std::enable_if_t<
1254  std::is_floating_point_v<ScalarType> ||
1255  (boost::is_complex<ScalarType>::value &&
1256  std::is_floating_point<typename internal::RemoveComplexWrapper<
1257  ScalarType>::type>::value)>>::is_tapeless = false;
1258 
1259 
1260  template <typename ScalarType>
1261  const bool NumberTraits<
1262  ScalarType,
1264  std::enable_if_t<
1265  std::is_floating_point_v<ScalarType> ||
1266  (boost::is_complex<ScalarType>::value &&
1267  std::is_floating_point<typename internal::RemoveComplexWrapper<
1268  ScalarType>::type>::value)>>::is_real_valued =
1269  (!boost::is_complex<ScalarType>::value);
1270 
1271 
1272  template <typename ScalarType>
1273  const bool NumberTraits<
1274  ScalarType,
1276  std::enable_if_t<
1277  std::is_floating_point_v<ScalarType> ||
1278  (boost::is_complex<ScalarType>::value &&
1279  std::is_floating_point<typename internal::RemoveComplexWrapper<
1280  ScalarType>::type>::value)>>::is_complex_valued =
1281  !(NumberTraits<ScalarType, NumberTypes::none>::is_real_valued);
1282 
1283 
1284  template <typename ScalarType>
1285  const unsigned int NumberTraits<
1286  ScalarType,
1288  std::enable_if_t<
1289  std::is_floating_point_v<ScalarType> ||
1290  (boost::is_complex<ScalarType>::value &&
1291  std::is_floating_point<typename internal::RemoveComplexWrapper<
1292  ScalarType>::type>::value)>>::n_supported_derivative_levels = 0;
1293 
1294 # else
1295 
1296  template <typename ScalarType>
1297  constexpr bool NumberTraits<
1298  ScalarType,
1300  std::enable_if_t<
1301  std::is_floating_point_v<ScalarType> ||
1302  (boost::is_complex<ScalarType>::value &&
1303  std::is_floating_point<typename internal::RemoveComplexWrapper<
1304  ScalarType>::type>::value)>>::is_taped;
1305 
1306 
1307  template <typename ScalarType>
1308  constexpr bool NumberTraits<
1309  ScalarType,
1311  std::enable_if_t<
1312  std::is_floating_point_v<ScalarType> ||
1313  (boost::is_complex<ScalarType>::value &&
1314  std::is_floating_point<typename internal::RemoveComplexWrapper<
1315  ScalarType>::type>::value)>>::is_tapeless;
1316 
1317 
1318  template <typename ScalarType>
1319  constexpr bool NumberTraits<
1320  ScalarType,
1322  std::enable_if_t<
1323  std::is_floating_point_v<ScalarType> ||
1324  (boost::is_complex<ScalarType>::value &&
1325  std::is_floating_point<typename internal::RemoveComplexWrapper<
1326  ScalarType>::type>::value)>>::is_real_valued;
1327 
1328 
1329  template <typename ScalarType>
1330  constexpr bool NumberTraits<
1331  ScalarType,
1333  std::enable_if_t<
1334  std::is_floating_point_v<ScalarType> ||
1335  (boost::is_complex<ScalarType>::value &&
1336  std::is_floating_point<typename internal::RemoveComplexWrapper<
1337  ScalarType>::type>::value)>>::is_complex_valued;
1338 
1339 
1340  template <typename ScalarType>
1341  constexpr unsigned int NumberTraits<
1342  ScalarType,
1344  std::enable_if_t<
1345  std::is_floating_point_v<ScalarType> ||
1346  (boost::is_complex<ScalarType>::value &&
1347  std::is_floating_point<typename internal::RemoveComplexWrapper<
1348  ScalarType>::type>::value)>>::n_supported_derivative_levels;
1349 
1350 # endif
1351 
1352 
1371  template <typename ScalarType>
1372  struct ADNumberTraits<
1373  ScalarType,
1374  std::enable_if_t<std::is_floating_point_v<ScalarType>>>
1375  : NumberTraits<ScalarType, NumberTypes::none>
1376  {};
1377 
1381  template <typename ComplexScalarType>
1382  struct ADNumberTraits<
1383  ComplexScalarType,
1384  std::enable_if_t<
1385  boost::is_complex<ComplexScalarType>::value &&
1386  std::is_floating_point_v<typename ComplexScalarType::value_type>>>
1387  : NumberTraits<ComplexScalarType, NumberTypes::none>
1388  {};
1389 
1390  } // namespace AD
1391 } // namespace Differentiation
1392 
1393 #endif // DOXYGEN
1394 
1396 
1397 #endif
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:477
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:478
#define Assert(cond, exc)
Definition: exceptions.h:1631
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
Definition: exceptions.h:1732
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:703