16 #ifndef dealii_differentiation_ad_ad_number_traits_h 17 #define dealii_differentiation_ad_ad_number_traits_h 19 #include <deal.II/base/exceptions.h> 20 #include <deal.II/differentiation/ad/ad_number_types.h> 22 #include <boost/type_traits.hpp> 25 #include <type_traits> 27 DEAL_II_NAMESPACE_OPEN
47 template<
typename ScalarType, enum NumberTypes ADNumberTypeCode,
typename T =
void>
66 template<
typename ADNumberType,
typename T =
void>
109 template<
typename ScalarType, enum NumberTypes ADNumberTypeCode,
typename =
void>
144 template<
typename ADNumberType,
typename T =
void>
179 template<
typename ADNumberType,
typename T =
void>
197 template <
typename ADNumberTrait,
typename T =
void>
217 template <
typename T>
227 template<
typename Number>
241 template <
typename NumberType>
253 template <
typename NumberType,
typename =
void>
265 template <
typename NumberType,
typename =
void>
277 template <
typename NumberType,
typename =
void>
289 template <
typename NumberType,
typename =
void>
308 template <
typename ADNumberTrait,
typename>
309 struct HasRequiredADInfo
324 template <
typename ADNumberTrait>
325 struct HasRequiredADInfo <ADNumberTrait, decltype(
326 (void) ADNumberTrait::type_code,
327 (void) ADNumberTrait::is_taped,
328 (void) std::declval<typename ADNumberTrait::real_type>(),
329 (void) std::declval<typename ADNumberTrait::derivative_type>(),
330 void() )> : std::true_type
339 template<
typename ScalarType>
340 struct Marking<ScalarType, typename
std::enable_if<
341 std::is_arithmetic<ScalarType>::value
351 template<
typename ADNumberType>
353 independent_variable(
const ScalarType &in,
364 template<
typename ADNumberType>
366 dependent_variable(ADNumberType &,
377 template<
typename ADNumberType>
378 struct Marking<ADNumberType, typename
std::enable_if<
379 boost::is_complex<ADNumberType>::value
386 template<
typename ScalarType>
388 independent_variable(
const ScalarType &in,
400 template<
typename ScalarType>
402 dependent_variable(ADNumberType &,
412 template <
typename NumberType,
typename>
413 struct is_taped_ad_number
418 template <
typename NumberType,
typename>
419 struct is_tapeless_ad_number
424 template <
typename NumberType,
typename>
425 struct is_real_valued_ad_number
430 template <
typename NumberType,
typename>
431 struct is_complex_valued_ad_number
441 template <
typename NumberType>
443 : internal::HasRequiredADInfo< ADNumberTraits<typename std::decay<NumberType>::type> >
451 template <
typename NumberType>
452 struct is_taped_ad_number<NumberType, typename
std::enable_if<
453 ADNumberTraits<typename std::decay<NumberType>::type>::is_taped
463 template <
typename NumberType>
464 struct is_tapeless_ad_number<NumberType, typename
std::enable_if<
465 ADNumberTraits<typename std::decay<NumberType>::type>::is_tapeless
475 template <
typename NumberType>
476 struct is_real_valued_ad_number<NumberType, typename
std::enable_if<
477 ADNumberTraits<typename std::decay<NumberType>::type>::is_real_valued
487 template <
typename NumberType>
488 struct is_complex_valued_ad_number<NumberType, typename
std::enable_if<
489 ADNumberTraits<typename std::decay<NumberType>::type>::is_complex_valued
502 template<
typename Number>
503 struct RemoveComplexWrapper
514 template<
typename Number>
515 struct RemoveComplexWrapper<
std::complex<Number> >
517 typedef typename RemoveComplexWrapper<Number>::type type;
526 template<
typename NumberType>
527 struct ExtractData<NumberType, typename
std::enable_if<
528 std::is_arithmetic<NumberType>::value
534 static const NumberType &
535 value (
const NumberType &x)
545 n_directional_derivatives (
const NumberType &)
555 directional_derivative (
const NumberType &,
568 template<
typename ADNumberType>
569 struct ExtractData<
std::complex<ADNumberType> >
573 "Expected an auto-differentiable number." 580 static std::complex<typename ADNumberTraits<ADNumberType>::scalar_type>
581 value (
const std::complex<ADNumberType> &x)
583 return std::complex<typename ADNumberTraits<ADNumberType>::scalar_type>(
584 ExtractData<ADNumberType>::value(x.real()),
585 ExtractData<ADNumberType>::value(x.imag()) );
593 n_directional_derivatives (
const std::complex<ADNumberType> &x)
595 return ExtractData<ADNumberType>::n_directional_derivatives(x.real());
602 static std::complex<typename ADNumberTraits<ADNumberType>::derivative_type>
603 directional_derivative (
const std::complex<ADNumberType> &x,
604 const unsigned int direction)
606 return std::complex<typename ADNumberTraits<ADNumberType>::derivative_type>(
607 ExtractData<ADNumberType>::directional_derivative(x.real(), direction),
608 ExtractData<ADNumberType>::directional_derivative(x.imag(), direction) );
613 template <
typename T>
622 typename std::enable_if<
623 !is_ad_number<F>::value
629 return ::internal::NumberType<T>::value(f);
641 typename std::enable_if<
642 is_ad_number<F>::value &&
643 std::is_arithmetic<T>::value
649 return NumberType<T>::value(ExtractData<F>::value(f));
661 typename std::enable_if<
662 is_ad_number<F>::value &&
663 is_ad_number<T>::value
670 template <
typename T>
671 struct NumberType<
std::complex<T> >
679 typename std::enable_if<
680 !is_ad_number<F>::value
686 return ::internal::NumberType< std::complex<T> >::value(f);
695 static std::complex<T>
697 typename std::enable_if<
698 is_ad_number<F>::value &&
699 std::is_arithmetic<T>::value
705 return std::complex<T>(NumberType<T>::value(ExtractData<F>::value(f)));
708 template <
typename F>
709 static std::complex<T>
710 value (
const std::complex<F> &f)
714 return std::complex<T>(
715 NumberType<T>::value(f.real()),
716 NumberType<T>::value(f.imag()));
744 template<
typename ScalarType, enum NumberTypes ADNumberTypeCode>
745 struct NumberTraits<ScalarType, ADNumberTypeCode, typename
std::enable_if<
746 std::is_floating_point<ScalarType>::value ||
747 (boost::is_complex<ScalarType>::value &&
748 std::is_floating_point<typename internal::RemoveComplexWrapper<ScalarType>::type>::value)
769 static const bool is_taped;
776 static const bool is_tapeless;
783 static const bool is_real_valued;
790 static const bool is_complex_valued;
797 static const unsigned int n_supported_derivative_levels;
805 static constexpr
bool is_taped
806 = internal::ADNumberInfoFromEnum<
807 typename internal::RemoveComplexWrapper<ScalarType>::type, ADNumberTypeCode
815 static constexpr
bool is_tapeless
816 = !(NumberTraits<ScalarType,ADNumberTypeCode>::is_taped);
823 static constexpr
bool is_real_valued
824 = (!boost::is_complex<ScalarType>::value);
831 static constexpr
bool is_complex_valued
832 = !(NumberTraits<ScalarType,ADNumberTypeCode>::is_real_valued);
839 static constexpr
unsigned int n_supported_derivative_levels
840 = internal::ADNumberInfoFromEnum<
841 typename internal::RemoveComplexWrapper<ScalarType>::type, ADNumberTypeCode
842 >::n_supported_derivative_levels;
851 typedef ScalarType scalar_type;
857 typedef typename internal::ADNumberInfoFromEnum<
858 typename internal::RemoveComplexWrapper<ScalarType>::type,ADNumberTypeCode
859 >::real_type real_type;
865 typedef std::complex<real_type> complex_type;
871 typedef typename std::conditional<
872 is_real_valued,real_type,complex_type
878 typedef typename std::conditional<
880 typename internal::ADNumberInfoFromEnum<
881 typename internal::RemoveComplexWrapper<ScalarType>::type,ADNumberTypeCode
883 std::complex<
typename internal::ADNumberInfoFromEnum<
884 typename internal::RemoveComplexWrapper<ScalarType>::type,ADNumberTypeCode
886 >::type derivative_type;
893 get_scalar_value(
const ad_type &x)
908 static derivative_type
909 get_directional_derivative(
const ad_type &x,
910 const unsigned int direction)
912 return internal::ExtractData<ad_type>::directional_derivative(x, direction);
921 n_directional_derivatives(
const ad_type &x)
923 return internal::ExtractData<ad_type>::n_directional_derivatives(x);
928 (is_real_valued==
true ?
929 std::is_same<ad_type,real_type>::value :
930 std::is_same<ad_type,complex_type>::value),
931 "Incorrect template type selected for ad_type");
934 (is_complex_valued==
true ?
935 boost::is_complex<scalar_type>::value :
937 "Expected a complex float_type");
940 (is_complex_valued==
true ?
941 boost::is_complex<ad_type>::value :
943 "Expected a complex ad_type");
949 template<
typename ScalarType, enum NumberTypes ADNumberTypeCode>
951 NumberTraits<ScalarType, ADNumberTypeCode,
typename std::enable_if<
952 std::is_floating_point<ScalarType>::value ||
953 (boost::is_complex<ScalarType>::value &&
954 std::is_floating_point<typename internal::RemoveComplexWrapper<ScalarType>::type>::value)
956 = internal::ADNumberInfoFromEnum<
957 typename internal::RemoveComplexWrapper<ScalarType>::type, ADNumberTypeCode
961 template<
typename ScalarType, enum NumberTypes ADNumberTypeCode>
963 NumberTraits<ScalarType, ADNumberTypeCode,
typename std::enable_if<
964 std::is_floating_point<ScalarType>::value ||
965 (boost::is_complex<ScalarType>::value &&
966 std::is_floating_point<typename internal::RemoveComplexWrapper<ScalarType>::type>::value)
967 >::type>::is_tapeless
968 = !(NumberTraits<ScalarType,ADNumberTypeCode>::is_taped);
971 template<
typename ScalarType, enum NumberTypes ADNumberTypeCode>
973 NumberTraits<ScalarType, ADNumberTypeCode,
typename std::enable_if<
974 std::is_floating_point<ScalarType>::value ||
975 (boost::is_complex<ScalarType>::value &&
976 std::is_floating_point<typename internal::RemoveComplexWrapper<ScalarType>::type>::value)
977 >::type>::is_real_valued
978 = (!boost::is_complex<ScalarType>::value);
981 template<
typename ScalarType, enum NumberTypes ADNumberTypeCode>
983 NumberTraits<ScalarType, ADNumberTypeCode,
typename std::enable_if<
984 std::is_floating_point<ScalarType>::value ||
985 (boost::is_complex<ScalarType>::value &&
986 std::is_floating_point<typename internal::RemoveComplexWrapper<ScalarType>::type>::value)
987 >::type>::is_complex_valued
988 = !(NumberTraits<ScalarType,ADNumberTypeCode>::is_real_valued);
991 template<
typename ScalarType, enum NumberTypes ADNumberTypeCode>
993 NumberTraits<ScalarType, ADNumberTypeCode,
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<ScalarType>::type>::value)
997 >::type>::n_supported_derivative_levels
998 = internal::ADNumberInfoFromEnum<
999 typename internal::RemoveComplexWrapper<ScalarType>::type, ADNumberTypeCode
1000 >::n_supported_derivative_levels;
1019 template<
typename ScalarType>
1020 struct ADNumberTraits<ScalarType, typename
std::enable_if<
1021 std::is_arithmetic<ScalarType>::value
1028 typedef ScalarType scalar_type;
1031 get_directional_derivative(
const ScalarType &,
1032 const unsigned int )
1052 template<
typename ADNumberType>
1054 is_nan (
const typename std::enable_if<
1056 ADNumberType>::type &x)
1064 DEAL_II_NAMESPACE_CLOSE
#define AssertThrow(cond, exc)
static ::ExceptionBase & ExcMessage(std::string arg1)
bool is_nan(const double x)