/**
* e
*/
- static const double E = 2.7182818284590452354;
+ static constexpr double E = 2.7182818284590452354;
/**
* log_2 e
*/
- static const double LOG2E = 1.4426950408889634074;
+ static constexpr double LOG2E = 1.4426950408889634074;
/**
* log_10 e
*/
- static const double LOG10E = 0.43429448190325182765;
+ static constexpr double LOG10E = 0.43429448190325182765;
/**
* log_e 2
*/
- static const double LN2 = 0.69314718055994530942;
+ static constexpr double LN2 = 0.69314718055994530942;
/**
* log_e 10
*/
- static const double LN10 = 2.30258509299404568402;
+ static constexpr double LN10 = 2.30258509299404568402;
/**
* pi
*/
- static const double PI = 3.14159265358979323846;
+ static constexpr double PI = 3.14159265358979323846;
/**
* pi/2
*/
- static const double PI_2 = 1.57079632679489661923;
+ static constexpr double PI_2 = 1.57079632679489661923;
/**
* pi/4
*/
- static const double PI_4 = 0.78539816339744830962;
+ static constexpr double PI_4 = 0.78539816339744830962;
/**
* sqrt(2)
*/
- static const double SQRT2 = 1.41421356237309504880;
+ static constexpr double SQRT2 = 1.41421356237309504880;
/**
* 1/sqrt(2)
*/
- static const double SQRT1_2 = 0.70710678118654752440;
+ static constexpr double SQRT1_2 = 0.70710678118654752440;
/**
* Check whether the given type can be used in CUDA device code.
* complex or real. Since the general template is selected for non-complex
* types, the answer is <code>false</code>.
*/
- static const bool is_complex = false;
+ static constexpr bool is_complex = false;
/**
* For this data type, alias the corresponding real type. Since the
*
* @note This function can also be used in CUDA device code.
*/
- static DEAL_II_CUDA_HOST_DEV const number &
- conjugate(const number &x);
+ static constexpr DEAL_II_CUDA_HOST_DEV const number &
+ conjugate(const number &x);
/**
* Return the square of the absolute value of the given number. Since the
* for this function.
*/
template <typename Dummy = number>
- static DEAL_II_CUDA_HOST_DEV
+ static constexpr DEAL_II_CUDA_HOST_DEV
typename std::enable_if<std::is_same<Dummy, number>::value &&
is_cuda_compatible<Dummy>::value,
real_type>::type
abs_square(const number &x);
template <typename Dummy = number>
- static typename std::enable_if<std::is_same<Dummy, number>::value &&
- !is_cuda_compatible<Dummy>::value,
- real_type>::type
- abs_square(const number &x);
+ static constexpr
+ typename std::enable_if<std::is_same<Dummy, number>::value &&
+ !is_cuda_compatible<Dummy>::value,
+ real_type>::type
+ abs_square(const number &x);
/**
* Return the absolute value of a number.
* complex or real. Since this specialization of the general template is
* selected for complex types, the answer is <code>true</code>.
*/
- static const bool is_complex = true;
+ static constexpr bool is_complex = true;
/**
* For this data type, alias the corresponding real type. Since this
/**
* Return the complex-conjugate of the given number.
*/
- static std::complex<number>
+ static constexpr std::complex<number>
conjugate(const std::complex<number> &x);
/**
* std::complex, this function returns the product of a number and its
* complex conjugate.
*/
- static real_type
+ static constexpr real_type
abs_square(const std::complex<number> &x);
template <typename number>
- DEAL_II_CUDA_HOST_DEV const number &
- NumberTraits<number>::conjugate(const number &x)
+ constexpr DEAL_II_CUDA_HOST_DEV const number &
+ NumberTraits<number>::conjugate(const number &x)
{
return x;
}
template <typename number>
template <typename Dummy>
- DEAL_II_CUDA_HOST_DEV
+ constexpr DEAL_II_CUDA_HOST_DEV
typename std::enable_if<std::is_same<Dummy, number>::value &&
is_cuda_compatible<Dummy>::value,
typename NumberTraits<number>::real_type>::type
template <typename number>
template <typename Dummy>
- typename std::enable_if<std::is_same<Dummy, number>::value &&
- !is_cuda_compatible<Dummy>::value,
- typename NumberTraits<number>::real_type>::type
- NumberTraits<number>::abs_square(const number &x)
+ constexpr
+ typename std::enable_if<std::is_same<Dummy, number>::value &&
+ !is_cuda_compatible<Dummy>::value,
+ typename NumberTraits<number>::real_type>::type
+ NumberTraits<number>::abs_square(const number &x)
{
return x * x;
}
template <typename number>
- std::complex<number>
+ constexpr std::complex<number>
NumberTraits<std::complex<number>>::conjugate(const std::complex<number> &x)
{
return std::conj(x);
template <typename number>
- typename NumberTraits<std::complex<number>>::real_type
+ constexpr typename NumberTraits<std::complex<number>>::real_type
NumberTraits<std::complex<number>>::abs_square(const std::complex<number> &x)
{
return std::norm(x);
template <typename T>
struct NumberType
{
- static DEAL_II_CUDA_HOST_DEV const T &
- value(const T &t)
+ static constexpr DEAL_II_CUDA_HOST_DEV const T &
+ value(const T &t)
{
return t;
}
// Type T is constructible from F.
template <typename F>
- static DEAL_II_CUDA_HOST_DEV T
- value(const F &f,
- typename std::enable_if<
+ static constexpr DEAL_II_CUDA_HOST_DEV T
+ value(const F &f,
+ typename std::enable_if<
!std::is_same<typename std::decay<T>::type,
typename std::decay<F>::type>::value &&
std::is_constructible<T, F>::value>::type * = nullptr)
// Type T is explicitly convertible (but not constructible) from F.
template <typename F>
- static T
+ static constexpr T
value(const F &f,
typename std::enable_if<
!std::is_same<typename std::decay<T>::type,
template <typename T>
struct NumberType<std::complex<T>>
{
- static const std::complex<T> &
+ static constexpr const std::complex<T> &
value(const std::complex<T> &t)
{
return t;
}
- static std::complex<T>
+ static constexpr std::complex<T>
value(const T &t)
{
return std::complex<T>(t);
// Facilitate cast from complex<double> to complex<float>
template <typename U>
- static std::complex<T>
+ static constexpr std::complex<T>
value(const std::complex<U> &t)
{
return std::complex<T>(NumberType<T>::value(t.real()),
* of an inlined function; the compiler may therefore produce more efficient
* code and you may use this value to declare other data types.
*/
- static const unsigned int dimension = dim;
+ static constexpr unsigned int dimension = dim;
/**
* Publish the rank of this tensor to the outside world.
*/
- static const unsigned int rank = 0;
+ static constexpr unsigned int rank = 0;
/**
* Number of independent components of a tensor of rank 0.
*/
- static const unsigned int n_independent_components = 1;
+ static constexpr unsigned int n_independent_components = 1;
/**
* Declare a type that has holds real-valued numbers with the same precision
/**
* Return a const pointer to the first element of the underlying storage.
*/
- const Number *
+ constexpr const Number *
begin_raw() const;
/**
* Return a const pointer to the element past the end of the underlying
* storage.
*/
- const Number *
+ constexpr const Number *
end_raw() const;
/**
* Test for inequality of two tensors.
*/
template <typename OtherNumber>
- bool
+ constexpr bool
operator!=(const Tensor<0, dim, OtherNumber> &rhs) const;
/**
/**
* Tensor with inverted entries.
*/
- Tensor
+ constexpr Tensor
operator-() const;
/**
* of an inlined function; the compiler may therefore produce more efficient
* code and you may use this value to declare other data types.
*/
- static const unsigned int dimension = dim;
+ static constexpr unsigned int dimension = dim;
/**
* Publish the rank of this tensor to the outside world.
*/
- static const unsigned int rank = rank_;
+ static constexpr unsigned int rank = rank_;
/**
* Number of independent components of a tensor of current rank. This is dim
* times the number of independent components of each sub-tensor.
*/
- static const unsigned int n_independent_components =
+ static constexpr unsigned int n_independent_components =
Tensor<rank_ - 1, dim>::n_independent_components * dim;
/**
*
* @note This function can also be used in CUDA device code.
*/
- DEAL_II_CUDA_HOST_DEV
+ constexpr DEAL_II_CUDA_HOST_DEV
Tensor() = default;
/**
* Conversion operator to tensor of tensors.
*/
template <typename OtherNumber>
+ constexpr
operator Tensor<1, dim, Tensor<rank_ - 1, dim, OtherNumber>>() const;
/**
*
* @note This function can also be used in CUDA device code.
*/
- DEAL_II_CUDA_HOST_DEV const value_type &
- operator[](const unsigned int i) const;
+ constexpr DEAL_II_CUDA_HOST_DEV const value_type &
+ operator[](const unsigned int i) const;
/**
* Read access using TableIndices <tt>indices</tt>
/**
* Return a const pointer to the first element of the underlying storage.
*/
- const Number *
+ constexpr const Number *
begin_raw() const;
/**
/**
* Return a pointer to the element past the end of the underlying storage.
*/
- const Number *
+ constexpr const Number *
end_raw() const;
/**
* Test for inequality of two tensors.
*/
template <typename OtherNumber>
- bool
+ constexpr bool
operator!=(const Tensor<rank_, dim, OtherNumber> &) const;
/**
* Determine an estimate for the memory consumption (in bytes) of this
* object.
*/
- static std::size_t
+ static constexpr std::size_t
memory_consumption();
/**
template <int rank, int dim, typename T>
struct NumberType<Tensor<rank, dim, T>>
{
- static const Tensor<rank, dim, T> &
+ static constexpr const Tensor<rank, dim, T> &
value(const Tensor<rank, dim, T> &t)
{
return t;
template <int rank, int dim, typename T>
struct NumberType<Tensor<rank, dim, VectorizedArray<T>>>
{
- static const Tensor<rank, dim, VectorizedArray<T>> &
+ static constexpr const Tensor<rank, dim, VectorizedArray<T>> &
value(const Tensor<rank, dim, VectorizedArray<T>> &t)
{
return t;
template <int dim, typename Number>
-inline DEAL_II_CUDA_HOST_DEV
-Tensor<0, dim, Number>::Tensor()
+DEAL_II_CUDA_HOST_DEV inline Tensor<0, dim, Number>::Tensor()
// Some auto-differentiable numbers need explicit
// zero initialization.
: value(internal::NumberType<Number>::value(0.0))
template <int dim, typename Number>
-inline const Number *
+constexpr const Number *
Tensor<0, dim, Number>::begin_raw() const
{
return std::addressof(value);
template <int dim, typename Number>
-inline const Number *
+constexpr const Number *
Tensor<0, dim, Number>::end_raw() const
{
return begin_raw() + n_independent_components;
template <int dim, typename Number>
template <typename OtherNumber>
-inline bool
+constexpr bool
Tensor<0, dim, Number>::operator!=(const Tensor<0, dim, OtherNumber> &p) const
{
return !((*this) == p);
namespace ComplexWorkaround
{
template <typename Number, typename OtherNumber>
- inline DEAL_II_CUDA_HOST_DEV void
+ constexpr DEAL_II_CUDA_HOST_DEV void
multiply_assign_scalar(Number &val, const OtherNumber &s)
{
val *= s;
#ifdef __CUDA_ARCH__
template <typename Number, typename OtherNumber>
- inline DEAL_II_CUDA_HOST_DEV void
+ constexpr DEAL_II_CUDA_HOST_DEV void
multiply_assign_scalar(std::complex<Number> &, const OtherNumber &)
{
printf("This function is not implemented for std::complex<Number>!\n");
template <int dim, typename Number>
-inline Tensor<0, dim, Number>
+constexpr Tensor<0, dim, Number>
Tensor<0, dim, Number>::operator-() const
{
return -value;
template <int rank_, int dim, typename Number>
template <typename OtherNumber>
-inline DEAL_II_ALWAYS_INLINE Tensor<rank_, dim, Number>::
- operator Tensor<1, dim, Tensor<rank_ - 1, dim, OtherNumber>>() const
+constexpr DEAL_II_ALWAYS_INLINE Tensor<rank_, dim, Number>::
+ operator Tensor<1, dim, Tensor<rank_ - 1, dim, OtherNumber>>() const
{
return Tensor<1, dim, Tensor<rank_ - 1, dim, Number>>(values);
}
template <int rank_, int dim, typename Number>
-inline DEAL_II_ALWAYS_INLINE
+constexpr DEAL_II_ALWAYS_INLINE
DEAL_II_CUDA_HOST_DEV const typename Tensor<rank_, dim, Number>::value_type &
Tensor<rank_, dim, Number>::operator[](const unsigned int i) const
{
template <int rank_, int dim, typename Number>
-inline const Number *
+constexpr const Number *
Tensor<rank_, dim, Number>::begin_raw() const
{
return std::addressof(
template <int rank_, int dim, typename Number>
-inline const Number *
+constexpr const Number *
Tensor<rank_, dim, Number>::end_raw() const
{
return begin_raw() + n_independent_components;
template <int rank_, int dim, typename Number>
template <typename OtherNumber>
-inline bool
+constexpr bool
Tensor<rank_, dim, Number>::
operator!=(const Tensor<rank_, dim, OtherNumber> &p) const
{
template <int rank_, int dim, typename Number>
-inline std::size_t
+constexpr std::size_t
Tensor<rank_, dim, Number>::memory_consumption()
{
return sizeof(Tensor<rank_, dim, Number>);
* @relatesalso Tensor<0,dim,Number>
*/
template <int dim, typename Number, typename Other>
-inline DEAL_II_ALWAYS_INLINE typename ProductType<Other, Number>::type
+constexpr DEAL_II_ALWAYS_INLINE typename ProductType<Other, Number>::type
operator*(const Other &object, const Tensor<0, dim, Number> &t)
{
return object * static_cast<const Number &>(t);
* @relatesalso Tensor<0,dim,Number>
*/
template <int dim, typename Number, typename Other>
-inline DEAL_II_ALWAYS_INLINE typename ProductType<Number, Other>::type
+constexpr DEAL_II_ALWAYS_INLINE typename ProductType<Number, Other>::type
operator*(const Tensor<0, dim, Number> &t, const Other &object)
{
return static_cast<const Number &>(t) * object;
* @relatesalso Tensor<0,dim,Number>
*/
template <int dim, typename Number, typename OtherNumber>
-inline DEAL_II_ALWAYS_INLINE typename ProductType<Number, OtherNumber>::type
+constexpr DEAL_II_ALWAYS_INLINE typename ProductType<Number, OtherNumber>::type
operator*(const Tensor<0, dim, Number> & src1,
const Tensor<0, dim, OtherNumber> &src2)
{
* @relatesalso Tensor<0,dim,Number>
*/
template <int dim, typename Number, typename OtherNumber>
-inline DEAL_II_ALWAYS_INLINE
+constexpr DEAL_II_ALWAYS_INLINE
Tensor<0,
dim,
typename ProductType<Number,
* @relatesalso Tensor<0,dim,Number>
*/
template <int dim, typename Number, typename OtherNumber>
-inline DEAL_II_ALWAYS_INLINE
+constexpr DEAL_II_ALWAYS_INLINE
Tensor<0, dim, typename ProductType<Number, OtherNumber>::type>
operator+(const Tensor<0, dim, Number> & p,
const Tensor<0, dim, OtherNumber> &q)
* @relatesalso Tensor<0,dim,Number>
*/
template <int dim, typename Number, typename OtherNumber>
-inline DEAL_II_ALWAYS_INLINE
+constexpr DEAL_II_ALWAYS_INLINE
Tensor<0, dim, typename ProductType<Number, OtherNumber>::type>
operator-(const Tensor<0, dim, Number> & p,
const Tensor<0, dim, OtherNumber> &q)
* @relatesalso Tensor
*/
template <int rank, int dim, typename Number, typename OtherNumber>
-inline DEAL_II_ALWAYS_INLINE
+constexpr DEAL_II_ALWAYS_INLINE
Tensor<rank,
dim,
typename ProductType<typename EnableIfScalar<Number>::type,
* @relatesalso Tensor
*/
template <typename Number>
-inline Number
+constexpr Number
determinant(const Tensor<2, 1, Number> &t)
{
return t[0][0];
* @author Jean-Paul Pelteret, 2016
*/
template <int dim, typename Number>
-inline Tensor<2, dim, Number>
+constexpr Tensor<2, dim, Number>
adjugate(const Tensor<2, dim, Number> &t)
{
return determinant(t) * invert(t);
* @author Jean-Paul Pelteret, 2016
*/
template <int dim, typename Number>
-inline Tensor<2, dim, Number>
+constexpr Tensor<2, dim, Number>
cofactor(const Tensor<2, dim, Number> &t)
{
return transpose(adjugate(t));