From c972a1a40f287ea52610f02fdda4cb2327d1b934 Mon Sep 17 00:00:00 2001 From: Reza Rastak Date: Sat, 13 Jul 2019 00:34:22 -0700 Subject: [PATCH] added constexpr to SymmetricTensor and TableIndices --- doc/news/changes/minor/20190713RezaRastak | 3 + include/deal.II/base/symmetric_tensor.h | 740 ++++++++---------- include/deal.II/base/table_indices.h | 119 ++- .../physics/elasticity/standard_tensors.h | 49 +- source/physics/elasticity/standard_tensors.cc | 4 +- 5 files changed, 412 insertions(+), 503 deletions(-) create mode 100644 doc/news/changes/minor/20190713RezaRastak diff --git a/doc/news/changes/minor/20190713RezaRastak b/doc/news/changes/minor/20190713RezaRastak new file mode 100644 index 0000000000..0ecbf23d08 --- /dev/null +++ b/doc/news/changes/minor/20190713RezaRastak @@ -0,0 +1,3 @@ +Improved: constexpr evaluation is enabled in SymmetricTensor and TableIndices +
+(Reza Rastak, 2019/07/13) \ No newline at end of file diff --git a/include/deal.II/base/symmetric_tensor.h b/include/deal.II/base/symmetric_tensor.h index 84a967aca0..84c62f5c32 100644 --- a/include/deal.II/base/symmetric_tensor.h +++ b/include/deal.II/base/symmetric_tensor.h @@ -32,36 +32,36 @@ template class SymmetricTensor; template -SymmetricTensor<2, dim, Number> -unit_symmetric_tensor(); +DEAL_II_CONSTEXPR SymmetricTensor<2, dim, Number> + unit_symmetric_tensor(); template -SymmetricTensor<4, dim, Number> -deviator_tensor(); +DEAL_II_CONSTEXPR SymmetricTensor<4, dim, Number> + deviator_tensor(); template -SymmetricTensor<4, dim, Number> -identity_tensor(); +DEAL_II_CONSTEXPR SymmetricTensor<4, dim, Number> + identity_tensor(); template -SymmetricTensor<2, dim, Number> +constexpr SymmetricTensor<2, dim, Number> invert(const SymmetricTensor<2, dim, Number> &); template -SymmetricTensor<4, dim, Number> +constexpr SymmetricTensor<4, dim, Number> invert(const SymmetricTensor<4, dim, Number> &); template -Number -trace(const SymmetricTensor<2, dim2, Number> &); +DEAL_II_CONSTEXPR Number + trace(const SymmetricTensor<2, dim2, Number> &); template -SymmetricTensor<2, dim, Number> -deviator(const SymmetricTensor<2, dim, Number> &); +DEAL_II_CONSTEXPR SymmetricTensor<2, dim, Number> + deviator(const SymmetricTensor<2, dim, Number> &); template -Number -determinant(const SymmetricTensor<2, dim, Number> &); +DEAL_II_CONSTEXPR Number + determinant(const SymmetricTensor<2, dim, Number> &); @@ -93,7 +93,7 @@ namespace internal * put at position position. The remaining indices remain in * invalid state. */ - inline TableIndices<2> + DEAL_II_CONSTEXPR inline TableIndices<2> merge(const TableIndices<2> &previous_indices, const unsigned int new_index, const unsigned int position) @@ -114,7 +114,7 @@ namespace internal * put at position position. The remaining indices remain in * invalid state. */ - inline TableIndices<4> + DEAL_II_CONSTEXPR inline TableIndices<4> merge(const TableIndices<4> &previous_indices, const unsigned int new_index, const unsigned int position) @@ -143,9 +143,10 @@ namespace internal previous_indices[1], previous_indices[2], new_index}; + default: + Assert(false, ExcInternalError()); + return {}; } - Assert(false, ExcInternalError()); - return {}; } @@ -293,12 +294,12 @@ namespace internal * @internal * * Class that acts as accessor to elements of type SymmetricTensor. The - * template parameter C may be either true or false, and + * template parameter constness may be either true or false, and * indicates whether the objects worked on are constant or not (i.e. write * access is only allowed if the value is false). * * Since with N indices, the effect of applying - * operator[] is getting access to something we N-1 + * operator[] is getting access to something with N-1 * indices, we have to implement these accessor classes recursively, with * stopping when we have only one index left. For the latter case, a * specialization of this class is declared below, where calling @@ -354,24 +355,25 @@ namespace internal * This guarantees that the accessor objects go out of scope earlier * than the mother object, avoid problems with data consistency. */ - Accessor(tensor_type &tensor, const TableIndices &previous_indices); + constexpr Accessor(tensor_type & tensor, + const TableIndices &previous_indices); /** * Copy constructor. */ - Accessor(const Accessor &) = default; + constexpr Accessor(const Accessor &) = default; public: /** * Index operator. */ - Accessor - operator[](const unsigned int i); + DEAL_II_CONSTEXPR Accessor + operator[](const unsigned int i); /** * Index operator. */ - Accessor + constexpr Accessor operator[](const unsigned int i) const; private: @@ -440,23 +442,24 @@ namespace internal * This guarantees that the accessor objects go out of scope earlier * than the mother object, avoid problems with data consistency. */ - Accessor(tensor_type &tensor, const TableIndices &previous_indices); + constexpr Accessor(tensor_type & tensor, + const TableIndices &previous_indices); /** * Copy constructor. */ - Accessor(const Accessor &) = default; + constexpr Accessor(const Accessor &) = default; public: /** * Index operator. */ - reference operator[](const unsigned int); + DEAL_II_CONSTEXPR reference operator[](const unsigned int); /** * Index operator. */ - reference operator[](const unsigned int) const; + constexpr reference operator[](const unsigned int) const; private: /** @@ -580,7 +583,7 @@ public: /** * Default constructor. Creates a tensor with all entries equal to zero. */ - SymmetricTensor(); + constexpr SymmetricTensor() = default; /** * Constructor. Generate a symmetric tensor from a general one. Assumes that @@ -593,7 +596,8 @@ public: * practice to check before calling symmetrize. */ template - explicit SymmetricTensor(const Tensor<2, dim, OtherNumber> &t); + DEAL_II_CONSTEXPR explicit SymmetricTensor( + const Tensor<2, dim, OtherNumber> &t); /** * A constructor that creates a symmetric tensor from an array holding its @@ -610,6 +614,7 @@ public: * the object from the internal namespace is to work around bugs in some * older compilers. */ + DEAL_II_CONSTEXPR SymmetricTensor(const Number (&array)[n_independent_components]); /** @@ -618,32 +623,32 @@ public: * Number. */ template - explicit SymmetricTensor( + constexpr explicit SymmetricTensor( const SymmetricTensor &initializer); /** * Return a pointer to the first element of the underlying storage. */ - Number * - begin_raw(); + DEAL_II_CONSTEXPR Number * + begin_raw(); /** * 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. */ - Number * - end_raw(); + DEAL_II_CONSTEXPR Number * + end_raw(); /** * Return a const pointer to the element past the end of the underlying * storage. */ - const Number * + constexpr const Number * end_raw() const; /** @@ -653,8 +658,8 @@ public: * @p Number. */ template - SymmetricTensor & - operator=(const SymmetricTensor &rhs); + DEAL_II_CONSTEXPR SymmetricTensor & + operator=(const SymmetricTensor &rhs); /** * This operator assigns a scalar to a tensor. To avoid confusion with what @@ -662,61 +667,61 @@ public: * value allowed for d, allowing the intuitive notation * t=0 to reset all elements of the tensor to zero. */ - SymmetricTensor & - operator=(const Number &d); + DEAL_II_CONSTEXPR SymmetricTensor & + operator=(const Number &d); /** * Convert the present symmetric tensor into a full tensor with the same * elements, but using the different storage scheme of full tensors. */ - operator Tensor() const; + constexpr operator Tensor() const; /** * Test for equality of two tensors. */ - bool + constexpr bool operator==(const SymmetricTensor &) const; /** * Test for inequality of two tensors. */ - bool + constexpr bool operator!=(const SymmetricTensor &) const; /** * Add another tensor. */ template - SymmetricTensor & - operator+=(const SymmetricTensor &); + DEAL_II_CONSTEXPR SymmetricTensor & + operator+=(const SymmetricTensor &); /** * Subtract another tensor. */ template - SymmetricTensor & - operator-=(const SymmetricTensor &); + DEAL_II_CONSTEXPR SymmetricTensor & + operator-=(const SymmetricTensor &); /** * Scale the tensor by factor, i.e. multiply all components by * factor. */ template - SymmetricTensor & - operator*=(const OtherNumber &factor); + DEAL_II_CONSTEXPR SymmetricTensor & + operator*=(const OtherNumber &factor); /** * Scale the tensor by 1/factor. */ template - SymmetricTensor & - operator/=(const OtherNumber &factor); + DEAL_II_CONSTEXPR SymmetricTensor & + operator/=(const OtherNumber &factor); /** * Unary minus operator. Negate all entries of a tensor. */ - SymmetricTensor - operator-() const; + DEAL_II_CONSTEXPR SymmetricTensor + operator-() const; /** * Product between the present symmetric tensor and a tensor of rank 2. For @@ -743,7 +748,7 @@ public: * they write it into the first argument to the function. */ template - typename internal::SymmetricTensorAccessors:: + DEAL_II_CONSTEXPR typename internal::SymmetricTensorAccessors:: double_contraction_result::type operator*(const SymmetricTensor<2, dim, OtherNumber> &s) const; @@ -752,27 +757,27 @@ public: * symmetric tensor given as argument. */ template - typename internal::SymmetricTensorAccessors:: + DEAL_II_CONSTEXPR typename internal::SymmetricTensorAccessors:: double_contraction_result::type operator*(const SymmetricTensor<4, dim, OtherNumber> &s) const; /** * Return a read-write reference to the indicated element. */ - Number & - operator()(const TableIndices &indices); + DEAL_II_CONSTEXPR Number & + operator()(const TableIndices &indices); /** * Return a @p const reference to the value referred to by the argument. */ - const Number & - operator()(const TableIndices &indices) const; + DEAL_II_CONSTEXPR const Number & + operator()(const TableIndices &indices) const; /** * Access the elements of a row of this symmetric tensor. This function is * called for constant tensors. */ - internal::SymmetricTensorAccessors:: + constexpr internal::SymmetricTensorAccessors:: Accessor operator[](const unsigned int row) const; @@ -780,7 +785,7 @@ public: * Access the elements of a row of this symmetric tensor. This function is * called for non-constant tensors. */ - internal::SymmetricTensorAccessors:: + DEAL_II_CONSTEXPR internal::SymmetricTensorAccessors:: Accessor operator[](const unsigned int row); @@ -789,30 +794,30 @@ public: * * Exactly the same as operator(). */ - const Number &operator[](const TableIndices &indices) const; + constexpr const Number &operator[](const TableIndices &indices) const; /** * Return a read-write reference to the indicated element. * * Exactly the same as operator(). */ - Number &operator[](const TableIndices &indices); + DEAL_II_CONSTEXPR Number &operator[](const TableIndices &indices); /** * Access to an element according to unrolled index. The function * s.access_raw_entry(unrolled_index) does the same as * s[s.unrolled_to_component_indices(i)], but more efficiently. */ - const Number & - access_raw_entry(const unsigned int unrolled_index) const; + DEAL_II_CONSTEXPR const Number & + access_raw_entry(const unsigned int unrolled_index) const; /** * Access to an element according to unrolled index. The function * s.access_raw_entry(unrolled_index) does the same as * s[s.unrolled_to_component_indices(i)], but more efficiently. */ - Number & - access_raw_entry(const unsigned int unrolled_index); + DEAL_II_CONSTEXPR Number & + access_raw_entry(const unsigned int unrolled_index); /** * Return the Frobenius-norm of a tensor, i.e. the square root of the sum of @@ -823,7 +828,7 @@ public: * upper right as well as lower left entries, not just one of them, although * they are equal for symmetric tensors). */ - typename numbers::NumberTraits::real_type + constexpr typename numbers::NumberTraits::real_type norm() const; /** @@ -833,7 +838,7 @@ public: * [0,n_independent_components) the given entry in a symmetric * tensor has. */ - static unsigned int + static constexpr unsigned int component_to_unrolled_index(const TableIndices &indices); /** @@ -841,7 +846,7 @@ public: * form of the tensor, return what set of indices $(k,l)$ (for rank-2 * tensors) or $(k,l,m,n)$ (for rank-4 tensors) corresponds to it. */ - static TableIndices + static constexpr TableIndices unrolled_to_component_indices(const unsigned int i); /** @@ -856,14 +861,14 @@ public: * and indeed the state where all elements have a zero value is the state * right after construction of such an object. */ - void + DEAL_II_CONSTEXPR void clear(); /** * Determine an estimate for the memory consumption (in bytes) of this * object. */ - static std::size_t + static constexpr std::size_t memory_consumption(); /** @@ -901,28 +906,28 @@ private: * Make a few more functions friends. */ template - friend Number2 - trace(const SymmetricTensor<2, dim2, Number2> &d); + friend DEAL_II_CONSTEXPR Number2 + trace(const SymmetricTensor<2, dim2, Number2> &d); template - friend Number2 - determinant(const SymmetricTensor<2, dim2, Number2> &t); + friend DEAL_II_CONSTEXPR Number2 + determinant(const SymmetricTensor<2, dim2, Number2> &t); template - friend SymmetricTensor<2, dim2, Number2> - deviator(const SymmetricTensor<2, dim2, Number2> &t); + friend DEAL_II_CONSTEXPR SymmetricTensor<2, dim2, Number2> + deviator(const SymmetricTensor<2, dim2, Number2> &t); template - friend SymmetricTensor<2, dim2, Number2> - unit_symmetric_tensor(); + friend DEAL_II_CONSTEXPR SymmetricTensor<2, dim2, Number2> + unit_symmetric_tensor(); template - friend SymmetricTensor<4, dim2, Number2> - deviator_tensor(); + friend DEAL_II_CONSTEXPR SymmetricTensor<4, dim2, Number2> + deviator_tensor(); template - friend SymmetricTensor<4, dim2, Number2> - identity_tensor(); + friend DEAL_II_CONSTEXPR SymmetricTensor<4, dim2, Number2> + identity_tensor(); /** @@ -954,7 +959,7 @@ namespace internal namespace SymmetricTensorAccessors { template - Accessor::Accessor( + constexpr Accessor::Accessor( tensor_type & tensor, const TableIndices &previous_indices) : tensor(tensor) @@ -964,7 +969,7 @@ namespace internal template - Accessor + DEAL_II_CONSTEXPR inline Accessor Accessor:: operator[](const unsigned int i) { @@ -975,7 +980,7 @@ namespace internal template - Accessor + constexpr Accessor Accessor:: operator[](const unsigned int i) const { @@ -986,7 +991,7 @@ namespace internal template - Accessor::Accessor( + constexpr Accessor::Accessor( tensor_type & tensor, const TableIndices &previous_indices) : tensor(tensor) @@ -996,16 +1001,17 @@ namespace internal template - typename Accessor::reference - Accessor:: - operator[](const unsigned int i) + DEAL_II_CONSTEXPR inline + typename Accessor::reference + Accessor:: + operator[](const unsigned int i) { return tensor(merge(previous_indices, i, rank_ - 1)); } template - typename Accessor::reference + constexpr typename Accessor::reference Accessor:: operator[](const unsigned int i) const { @@ -1016,19 +1022,9 @@ namespace internal -template -inline SymmetricTensor::SymmetricTensor() -{ - // Some auto-differentiable numbers need explicit - // zero initialization. - for (unsigned int i = 0; i < base_tensor_type::dimension; ++i) - data[i] = internal::NumberType::value(0.0); -} - - template template -inline SymmetricTensor::SymmetricTensor( +DEAL_II_CONSTEXPR inline SymmetricTensor::SymmetricTensor( const Tensor<2, dim, OtherNumber> &t) { Assert(rank == 2, ExcNotImplemented()); @@ -1073,19 +1069,15 @@ inline SymmetricTensor::SymmetricTensor( template template -inline SymmetricTensor::SymmetricTensor( +constexpr SymmetricTensor::SymmetricTensor( const SymmetricTensor &initializer) -{ - for (unsigned int i = 0; i < base_tensor_type::dimension; ++i) - data[i] = - internal::NumberType::value( - initializer.data[i]); -} + : data(initializer.data) +{} template -inline SymmetricTensor::SymmetricTensor( +DEAL_II_CONSTEXPR inline SymmetricTensor::SymmetricTensor( const Number (&array)[n_independent_components]) : data( *reinterpret_cast(array)) @@ -1099,19 +1091,18 @@ inline SymmetricTensor::SymmetricTensor( template template -inline SymmetricTensor & +DEAL_II_CONSTEXPR inline SymmetricTensor & SymmetricTensor:: operator=(const SymmetricTensor &t) { - for (unsigned int i = 0; i < base_tensor_type::dimension; ++i) - data[i] = t.data[i]; + data = t.data; return *this; } template -inline SymmetricTensor & +DEAL_II_CONSTEXPR inline SymmetricTensor & SymmetricTensor::operator=(const Number &d) { Assert(numbers::value_is_zero(d), @@ -1129,8 +1120,9 @@ namespace internal namespace SymmetricTensorImplementation { template - inline DEAL_II_ALWAYS_INLINE dealii::Tensor<2, dim, Number> - convert_to_tensor(const dealii::SymmetricTensor<2, dim, Number> &s) + DEAL_II_CONSTEXPR inline DEAL_II_ALWAYS_INLINE + dealii::Tensor<2, dim, Number> + convert_to_tensor(const dealii::SymmetricTensor<2, dim, Number> &s) { dealii::Tensor<2, dim, Number> t; @@ -1150,8 +1142,8 @@ namespace internal template - dealii::Tensor<4, dim, Number> - convert_to_tensor(const dealii::SymmetricTensor<4, dim, Number> &st) + DEAL_II_CONSTEXPR dealii::Tensor<4, dim, Number> + convert_to_tensor(const dealii::SymmetricTensor<4, dim, Number> &st) { // utilize the symmetry properties of SymmetricTensor<4,dim> // discussed in the class documentation to avoid accessing all @@ -1174,7 +1166,7 @@ namespace internal template struct Inverse<2, 1, Number> { - static inline dealii::SymmetricTensor<2, 1, Number> + DEAL_II_CONSTEXPR static inline dealii::SymmetricTensor<2, 1, Number> value(const dealii::SymmetricTensor<2, 1, Number> &t) { dealii::SymmetricTensor<2, 1, Number> tmp; @@ -1189,7 +1181,7 @@ namespace internal template struct Inverse<2, 2, Number> { - static inline dealii::SymmetricTensor<2, 2, Number> + DEAL_II_CONSTEXPR static inline dealii::SymmetricTensor<2, 2, Number> value(const dealii::SymmetricTensor<2, 2, Number> &t) { dealii::SymmetricTensor<2, 2, Number> tmp; @@ -1215,7 +1207,7 @@ namespace internal template struct Inverse<2, 3, Number> { - static dealii::SymmetricTensor<2, 3, Number> + DEAL_II_CONSTEXPR static dealii::SymmetricTensor<2, 3, Number> value(const dealii::SymmetricTensor<2, 3, Number> &t) { dealii::SymmetricTensor<2, 3, Number> tmp; @@ -1282,7 +1274,7 @@ namespace internal template struct Inverse<4, 1, Number> { - static inline dealii::SymmetricTensor<4, 1, Number> + DEAL_II_CONSTEXPR static inline dealii::SymmetricTensor<4, 1, Number> value(const dealii::SymmetricTensor<4, 1, Number> &t) { dealii::SymmetricTensor<4, 1, Number> tmp; @@ -1295,7 +1287,7 @@ namespace internal template struct Inverse<4, 2, Number> { - static inline dealii::SymmetricTensor<4, 2, Number> + DEAL_II_CONSTEXPR static inline dealii::SymmetricTensor<4, 2, Number> value(const dealii::SymmetricTensor<4, 2, Number> &t) { dealii::SymmetricTensor<4, 2, Number> tmp; @@ -1471,8 +1463,8 @@ namespace internal template -inline DEAL_II_ALWAYS_INLINE SymmetricTensor:: - operator Tensor() const +constexpr DEAL_II_ALWAYS_INLINE SymmetricTensor:: + operator Tensor() const { return internal::SymmetricTensorImplementation::convert_to_tensor(*this); } @@ -1480,7 +1472,7 @@ inline DEAL_II_ALWAYS_INLINE SymmetricTensor:: template -inline bool +constexpr bool SymmetricTensor:: operator==(const SymmetricTensor &t) const { @@ -1490,7 +1482,7 @@ operator==(const SymmetricTensor &t) const template -inline bool +constexpr bool SymmetricTensor:: operator!=(const SymmetricTensor &t) const { @@ -1501,9 +1493,10 @@ operator!=(const SymmetricTensor &t) const template template -inline DEAL_II_ALWAYS_INLINE SymmetricTensor & - SymmetricTensor:: - operator+=(const SymmetricTensor &t) +DEAL_II_CONSTEXPR inline DEAL_II_ALWAYS_INLINE + SymmetricTensor & + SymmetricTensor:: + operator+=(const SymmetricTensor &t) { data += t.data; return *this; @@ -1513,9 +1506,10 @@ inline DEAL_II_ALWAYS_INLINE SymmetricTensor & template template -inline DEAL_II_ALWAYS_INLINE SymmetricTensor & - SymmetricTensor:: - operator-=(const SymmetricTensor &t) +DEAL_II_CONSTEXPR inline DEAL_II_ALWAYS_INLINE + SymmetricTensor & + SymmetricTensor:: + operator-=(const SymmetricTensor &t) { data -= t.data; return *this; @@ -1525,8 +1519,9 @@ inline DEAL_II_ALWAYS_INLINE SymmetricTensor & template template -inline DEAL_II_ALWAYS_INLINE SymmetricTensor & -SymmetricTensor::operator*=(const OtherNumber &d) +DEAL_II_CONSTEXPR inline DEAL_II_ALWAYS_INLINE + SymmetricTensor & + SymmetricTensor::operator*=(const OtherNumber &d) { data *= d; return *this; @@ -1536,8 +1531,9 @@ SymmetricTensor::operator*=(const OtherNumber &d) template template -inline DEAL_II_ALWAYS_INLINE SymmetricTensor & -SymmetricTensor::operator/=(const OtherNumber &d) +DEAL_II_CONSTEXPR inline DEAL_II_ALWAYS_INLINE + SymmetricTensor & + SymmetricTensor::operator/=(const OtherNumber &d) { data /= d; return *this; @@ -1546,8 +1542,9 @@ SymmetricTensor::operator/=(const OtherNumber &d) template -inline DEAL_II_ALWAYS_INLINE SymmetricTensor -SymmetricTensor::operator-() const +DEAL_II_CONSTEXPR inline DEAL_II_ALWAYS_INLINE + SymmetricTensor + SymmetricTensor::operator-() const { SymmetricTensor tmp = *this; tmp.data = -tmp.data; @@ -1557,7 +1554,7 @@ SymmetricTensor::operator-() const template -inline DEAL_II_ALWAYS_INLINE void +DEAL_II_CONSTEXPR inline DEAL_II_ALWAYS_INLINE void SymmetricTensor::clear() { data.clear(); @@ -1566,7 +1563,7 @@ SymmetricTensor::clear() template -inline std::size_t +constexpr std::size_t SymmetricTensor::memory_consumption() { // all memory consists of statically allocated memory of the current @@ -1579,13 +1576,14 @@ SymmetricTensor::memory_consumption() namespace internal { template - inline DEAL_II_ALWAYS_INLINE typename SymmetricTensorAccessors:: - double_contraction_result<2, 2, dim, Number, OtherNumber>::type - perform_double_contraction( - const typename SymmetricTensorAccessors::StorageType<2, dim, Number>:: - base_tensor_type &data, - const typename SymmetricTensorAccessors:: - StorageType<2, dim, OtherNumber>::base_tensor_type &sdata) + DEAL_II_CONSTEXPR inline DEAL_II_ALWAYS_INLINE + typename SymmetricTensorAccessors:: + double_contraction_result<2, 2, dim, Number, OtherNumber>::type + perform_double_contraction( + const typename SymmetricTensorAccessors::StorageType<2, dim, Number>:: + base_tensor_type &data, + const typename SymmetricTensorAccessors:: + StorageType<2, dim, OtherNumber>::base_tensor_type &sdata) { using result_type = typename SymmetricTensorAccessors:: double_contraction_result<2, 2, dim, Number, OtherNumber>::type; @@ -1613,7 +1611,7 @@ namespace internal template - inline typename SymmetricTensorAccessors:: + DEAL_II_CONSTEXPR inline typename SymmetricTensorAccessors:: double_contraction_result<4, 2, dim, Number, OtherNumber>::type perform_double_contraction( const typename SymmetricTensorAccessors::StorageType<4, dim, Number>:: @@ -1638,7 +1636,7 @@ namespace internal template - inline typename SymmetricTensorAccessors::StorageType< + DEAL_II_CONSTEXPR inline typename SymmetricTensorAccessors::StorageType< 2, dim, typename SymmetricTensorAccessors:: @@ -1675,7 +1673,7 @@ namespace internal template - inline typename SymmetricTensorAccessors::StorageType< + DEAL_II_CONSTEXPR inline typename SymmetricTensorAccessors::StorageType< 4, dim, typename SymmetricTensorAccessors:: @@ -1716,10 +1714,11 @@ namespace internal template template -inline DEAL_II_ALWAYS_INLINE typename internal::SymmetricTensorAccessors:: - double_contraction_result::type - SymmetricTensor:: - operator*(const SymmetricTensor<2, dim, OtherNumber> &s) const +DEAL_II_CONSTEXPR inline DEAL_II_ALWAYS_INLINE + typename internal::SymmetricTensorAccessors:: + double_contraction_result::type + SymmetricTensor:: + operator*(const SymmetricTensor<2, dim, OtherNumber> &s) const { // need to have two different function calls // because a scalar and rank-2 tensor are not @@ -1733,7 +1732,7 @@ inline DEAL_II_ALWAYS_INLINE typename internal::SymmetricTensorAccessors:: template template -inline typename internal::SymmetricTensorAccessors:: +DEAL_II_CONSTEXPR inline typename internal::SymmetricTensorAccessors:: double_contraction_result::type SymmetricTensor:: operator*(const SymmetricTensor<4, dim, OtherNumber> &s) const @@ -1758,8 +1757,23 @@ inline typename internal::SymmetricTensorAccessors:: // into a separate namespace namespace internal { + // The variables within this struct will be referenced in the next functions. + // It is a workaround that allows returning a reference to a static variable + // while allowing constexpr evaluation of the function. + // It has to be defined outside the function because constexpr functions + // cannot define static variables. + // A similar struct has also been defined in tensor.h + template + struct Uninitialized + { + static Type value; + }; + + template + Type Uninitialized::value; + template - inline Number & + DEAL_II_CONSTEXPR inline Number & symmetric_tensor_access(const TableIndices<2> &indices, typename SymmetricTensorAccessors:: StorageType<2, dim, Number>::base_tensor_type &data) @@ -1797,14 +1811,16 @@ namespace internal } } - static Number dummy_but_referenceable = Number(); - return dummy_but_referenceable; + // The code should never reach there. + // Returns a dummy reference to a dummy variable just to make the + // compiler happy. + return Uninitialized::value; } template - inline const Number & + DEAL_II_CONSTEXPR inline const Number & symmetric_tensor_access(const TableIndices<2> &indices, const typename SymmetricTensorAccessors:: StorageType<2, dim, Number>::base_tensor_type &data) @@ -1831,9 +1847,8 @@ namespace internal default: // to do the rest, sort our indices before comparing { - TableIndices<2> sorted_indices(indices); - sorted_indices.sort(); - + TableIndices<2> sorted_indices(std::min(indices[0], indices[1]), + std::max(indices[0], indices[1])); for (unsigned int d = 0, c = 0; d < dim; ++d) for (unsigned int e = d + 1; e < dim; ++e, ++c) if ((sorted_indices[0] == d) && (sorted_indices[1] == e)) @@ -1842,14 +1857,16 @@ namespace internal } } - static Number dummy_but_referenceable = Number(); - return dummy_but_referenceable; + // The code should never reach there. + // Returns a dummy reference to a dummy variable just to make the + // compiler happy. + return Uninitialized::value; } template - inline Number & + DEAL_II_CONSTEXPR inline Number & symmetric_tensor_access(const TableIndices<4> &indices, typename SymmetricTensorAccessors:: StorageType<4, dim, Number>::base_tensor_type &data) @@ -1860,100 +1877,43 @@ namespace internal return data[0][0]; case 2: - // each entry of the tensor can be - // thought of as an entry in a - // matrix that maps the rolled-out - // rank-2 tensors into rolled-out - // rank-2 tensors. this is the - // format in which we store rank-4 - // tensors. determine which - // position the present entry is + // each entry of the tensor can be thought of as an entry in a + // matrix that maps the rolled-out rank-2 tensors into rolled-out + // rank-2 tensors. this is the format in which we store rank-4 + // tensors. determine which position the present entry is // stored in { - unsigned int base_index[2]; - if ((indices[0] == 0) && (indices[1] == 0)) - base_index[0] = 0; - else if ((indices[0] == 1) && (indices[1] == 1)) - base_index[0] = 1; - else - base_index[0] = 2; - - if ((indices[2] == 0) && (indices[3] == 0)) - base_index[1] = 0; - else if ((indices[2] == 1) && (indices[3] == 1)) - base_index[1] = 1; - else - base_index[1] = 2; - - return data[base_index[0]][base_index[1]]; + constexpr std::size_t base_index[2][2] = {{0, 2}, {2, 1}}; + return data[base_index[indices[0]][indices[1]]] + [base_index[indices[2]][indices[3]]]; } - case 3: - // each entry of the tensor can be - // thought of as an entry in a - // matrix that maps the rolled-out - // rank-2 tensors into rolled-out - // rank-2 tensors. this is the - // format in which we store rank-4 - // tensors. determine which - // position the present entry is + // each entry of the tensor can be thought of as an entry in a + // matrix that maps the rolled-out rank-2 tensors into rolled-out + // rank-2 tensors. this is the format in which we store rank-4 + // tensors. determine which position the present entry is // stored in { - unsigned int base_index[2]; - if ((indices[0] == 0) && (indices[1] == 0)) - base_index[0] = 0; - else if ((indices[0] == 1) && (indices[1] == 1)) - base_index[0] = 1; - else if ((indices[0] == 2) && (indices[1] == 2)) - base_index[0] = 2; - else if (((indices[0] == 0) && (indices[1] == 1)) || - ((indices[0] == 1) && (indices[1] == 0))) - base_index[0] = 3; - else if (((indices[0] == 0) && (indices[1] == 2)) || - ((indices[0] == 2) && (indices[1] == 0))) - base_index[0] = 4; - else - { - Assert(((indices[0] == 1) && (indices[1] == 2)) || - ((indices[0] == 2) && (indices[1] == 1)), - ExcInternalError()); - base_index[0] = 5; - } - - if ((indices[2] == 0) && (indices[3] == 0)) - base_index[1] = 0; - else if ((indices[2] == 1) && (indices[3] == 1)) - base_index[1] = 1; - else if ((indices[2] == 2) && (indices[3] == 2)) - base_index[1] = 2; - else if (((indices[2] == 0) && (indices[3] == 1)) || - ((indices[2] == 1) && (indices[3] == 0))) - base_index[1] = 3; - else if (((indices[2] == 0) && (indices[3] == 2)) || - ((indices[2] == 2) && (indices[3] == 0))) - base_index[1] = 4; - else - { - Assert(((indices[2] == 1) && (indices[3] == 2)) || - ((indices[2] == 2) && (indices[3] == 1)), - ExcInternalError()); - base_index[1] = 5; - } - - return data[base_index[0]][base_index[1]]; + constexpr std::size_t base_index[3][3] = {{0, 3, 4}, + {3, 1, 5}, + {4, 5, 2}}; + return data[base_index[indices[0]][indices[1]]] + [base_index[indices[2]][indices[3]]]; } default: Assert(false, ExcNotImplemented()); } - static Number dummy; - return dummy; + // The code should never reach there. + // Returns a dummy reference to a dummy variable just to make the + // compiler happy. + return Uninitialized::value; } template - inline const Number & + DEAL_II_CONSTEXPR inline const Number & symmetric_tensor_access(const TableIndices<4> &indices, const typename SymmetricTensorAccessors:: StorageType<4, dim, Number>::base_tensor_type &data) @@ -1964,95 +1924,38 @@ namespace internal return data[0][0]; case 2: - // each entry of the tensor can be - // thought of as an entry in a - // matrix that maps the rolled-out - // rank-2 tensors into rolled-out - // rank-2 tensors. this is the - // format in which we store rank-4 - // tensors. determine which - // position the present entry is + // each entry of the tensor can be thought of as an entry in a + // matrix that maps the rolled-out rank-2 tensors into rolled-out + // rank-2 tensors. this is the format in which we store rank-4 + // tensors. determine which position the present entry is // stored in { - unsigned int base_index[2]; - if ((indices[0] == 0) && (indices[1] == 0)) - base_index[0] = 0; - else if ((indices[0] == 1) && (indices[1] == 1)) - base_index[0] = 1; - else - base_index[0] = 2; - - if ((indices[2] == 0) && (indices[3] == 0)) - base_index[1] = 0; - else if ((indices[2] == 1) && (indices[3] == 1)) - base_index[1] = 1; - else - base_index[1] = 2; - - return data[base_index[0]][base_index[1]]; + constexpr std::size_t base_index[2][2] = {{0, 2}, {2, 1}}; + return data[base_index[indices[0]][indices[1]]] + [base_index[indices[2]][indices[3]]]; } - case 3: - // each entry of the tensor can be - // thought of as an entry in a - // matrix that maps the rolled-out - // rank-2 tensors into rolled-out - // rank-2 tensors. this is the - // format in which we store rank-4 - // tensors. determine which - // position the present entry is + // each entry of the tensor can be thought of as an entry in a + // matrix that maps the rolled-out rank-2 tensors into rolled-out + // rank-2 tensors. this is the format in which we store rank-4 + // tensors. determine which position the present entry is // stored in { - unsigned int base_index[2]; - if ((indices[0] == 0) && (indices[1] == 0)) - base_index[0] = 0; - else if ((indices[0] == 1) && (indices[1] == 1)) - base_index[0] = 1; - else if ((indices[0] == 2) && (indices[1] == 2)) - base_index[0] = 2; - else if (((indices[0] == 0) && (indices[1] == 1)) || - ((indices[0] == 1) && (indices[1] == 0))) - base_index[0] = 3; - else if (((indices[0] == 0) && (indices[1] == 2)) || - ((indices[0] == 2) && (indices[1] == 0))) - base_index[0] = 4; - else - { - Assert(((indices[0] == 1) && (indices[1] == 2)) || - ((indices[0] == 2) && (indices[1] == 1)), - ExcInternalError()); - base_index[0] = 5; - } - - if ((indices[2] == 0) && (indices[3] == 0)) - base_index[1] = 0; - else if ((indices[2] == 1) && (indices[3] == 1)) - base_index[1] = 1; - else if ((indices[2] == 2) && (indices[3] == 2)) - base_index[1] = 2; - else if (((indices[2] == 0) && (indices[3] == 1)) || - ((indices[2] == 1) && (indices[3] == 0))) - base_index[1] = 3; - else if (((indices[2] == 0) && (indices[3] == 2)) || - ((indices[2] == 2) && (indices[3] == 0))) - base_index[1] = 4; - else - { - Assert(((indices[2] == 1) && (indices[3] == 2)) || - ((indices[2] == 2) && (indices[3] == 1)), - ExcInternalError()); - base_index[1] = 5; - } - - return data[base_index[0]][base_index[1]]; + constexpr std::size_t base_index[3][3] = {{0, 3, 4}, + {3, 1, 5}, + {4, 5, 2}}; + return data[base_index[indices[0]][indices[1]]] + [base_index[indices[2]][indices[3]]]; } default: Assert(false, ExcNotImplemented()); } - static Number dummy; - return dummy; + // The code should never reach there. + // Returns a dummy reference to a dummy variable just to make the + // compiler happy. + return Uninitialized::value; } } // end of namespace internal @@ -2060,7 +1963,7 @@ namespace internal template -inline Number & +DEAL_II_CONSTEXPR inline Number & SymmetricTensor:: operator()(const TableIndices &indices) { @@ -2072,7 +1975,7 @@ operator()(const TableIndices &indices) template -inline const Number & +DEAL_II_CONSTEXPR inline const Number & SymmetricTensor:: operator()(const TableIndices &indices) const { @@ -2088,7 +1991,7 @@ namespace internal namespace SymmetricTensorImplementation { template - TableIndices + constexpr TableIndices get_partially_filled_indices(const unsigned int row, const std::integral_constant &) { @@ -2097,7 +2000,7 @@ namespace internal template - TableIndices + constexpr TableIndices get_partially_filled_indices(const unsigned int row, const std::integral_constant &) { @@ -2111,7 +2014,7 @@ namespace internal template -internal::SymmetricTensorAccessors:: +constexpr internal::SymmetricTensorAccessors:: Accessor SymmetricTensor:: operator[](const unsigned int row) const @@ -2126,7 +2029,7 @@ internal::SymmetricTensorAccessors:: template -internal::SymmetricTensorAccessors:: +DEAL_II_CONSTEXPR inline internal::SymmetricTensorAccessors:: Accessor SymmetricTensor::operator[](const unsigned int row) { @@ -2140,8 +2043,8 @@ internal::SymmetricTensorAccessors:: template -inline const Number &SymmetricTensor:: - operator[](const TableIndices &indices) const +constexpr const Number &SymmetricTensor:: + operator[](const TableIndices &indices) const { return operator()(indices); } @@ -2149,8 +2052,8 @@ inline const Number &SymmetricTensor:: template -inline Number &SymmetricTensor:: - operator[](const TableIndices &indices) +DEAL_II_CONSTEXPR inline Number &SymmetricTensor:: + operator[](const TableIndices &indices) { return operator()(indices); } @@ -2158,7 +2061,7 @@ inline Number &SymmetricTensor:: template -inline Number * +DEAL_II_CONSTEXPR inline Number * SymmetricTensor::begin_raw() { return std::addressof(this->access_raw_entry(0)); @@ -2167,7 +2070,7 @@ SymmetricTensor::begin_raw() template -inline const Number * +constexpr const Number * SymmetricTensor::begin_raw() const { return std::addressof(this->access_raw_entry(0)); @@ -2176,7 +2079,7 @@ SymmetricTensor::begin_raw() const template -inline Number * +DEAL_II_CONSTEXPR inline Number * SymmetricTensor::end_raw() { return begin_raw() + n_independent_components; @@ -2185,7 +2088,7 @@ SymmetricTensor::end_raw() template -inline const Number * +constexpr const Number * SymmetricTensor::end_raw() const { return begin_raw() + n_independent_components; @@ -2198,7 +2101,7 @@ namespace internal namespace SymmetricTensorImplementation { template - unsigned int + constexpr unsigned int entry_to_indices(const dealii::SymmetricTensor<2, dim, Number> &, const unsigned int index) { @@ -2207,7 +2110,7 @@ namespace internal template - dealii::TableIndices<2> + constexpr dealii::TableIndices<2> entry_to_indices(const dealii::SymmetricTensor<4, dim, Number> &, const unsigned int index) { @@ -2221,7 +2124,7 @@ namespace internal template -inline const Number & +DEAL_II_CONSTEXPR inline const Number & SymmetricTensor::access_raw_entry( const unsigned int index) const { @@ -2233,7 +2136,7 @@ SymmetricTensor::access_raw_entry( template -inline Number & +DEAL_II_CONSTEXPR inline Number & SymmetricTensor::access_raw_entry(const unsigned int index) { AssertIndexRange(index, n_independent_components); @@ -2246,7 +2149,7 @@ SymmetricTensor::access_raw_entry(const unsigned int index) namespace internal { template - inline typename numbers::NumberTraits::real_type + DEAL_II_CONSTEXPR inline typename numbers::NumberTraits::real_type compute_norm(const typename SymmetricTensorAccessors:: StorageType<2, dim, Number>::base_tensor_type &data) { @@ -2290,7 +2193,7 @@ namespace internal template - inline typename numbers::NumberTraits::real_type + DEAL_II_CONSTEXPR inline typename numbers::NumberTraits::real_type compute_norm(const typename SymmetricTensorAccessors:: StorageType<4, dim, Number>::base_tensor_type &data) { @@ -2333,7 +2236,7 @@ namespace internal template -inline typename numbers::NumberTraits::real_type +constexpr typename numbers::NumberTraits::real_type SymmetricTensor::norm() const { return internal::compute_norm(data); @@ -2351,7 +2254,7 @@ namespace internal // // this function is for rank-2 tensors template - inline unsigned int + DEAL_II_CONSTEXPR inline unsigned int component_to_unrolled_index(const TableIndices<2> &indices) { Assert(indices[0] < dim, ExcIndexRange(indices[0], 0, dim)); @@ -2366,24 +2269,24 @@ namespace internal case 2: { - static const unsigned int table[2][2] = {{0, 2}, {2, 1}}; + constexpr unsigned int table[2][2] = {{0, 2}, {2, 1}}; return table[indices[0]][indices[1]]; } case 3: { - static const unsigned int table[3][3] = {{0, 3, 4}, - {3, 1, 5}, - {4, 5, 2}}; + constexpr unsigned int table[3][3] = {{0, 3, 4}, + {3, 1, 5}, + {4, 5, 2}}; return table[indices[0]][indices[1]]; } case 4: { - static const unsigned int table[4][4] = {{0, 4, 5, 6}, - {4, 1, 7, 8}, - {5, 7, 2, 9}, - {6, 8, 9, 3}}; + constexpr unsigned int table[4][4] = {{0, 4, 5, 6}, + {4, 1, 7, 8}, + {5, 7, 2, 9}, + {6, 8, 9, 3}}; return table[indices[0]][indices[1]]; } @@ -2415,7 +2318,7 @@ namespace internal // this function is for tensors of ranks not already handled // above template - inline unsigned int + DEAL_II_CONSTEXPR inline unsigned int component_to_unrolled_index(const TableIndices &indices) { (void)indices; @@ -2427,7 +2330,7 @@ namespace internal template -inline unsigned int +constexpr unsigned int SymmetricTensor::component_to_unrolled_index( const TableIndices &indices) { @@ -2449,7 +2352,7 @@ namespace internal // // this function is for rank-2 tensors template - inline TableIndices<2> + DEAL_II_CONSTEXPR inline TableIndices<2> unrolled_to_component_indices(const unsigned int i, const std::integral_constant &) { @@ -2509,7 +2412,7 @@ namespace internal // this function is for tensors of a rank not already handled // above template - inline TableIndices + DEAL_II_CONSTEXPR inline TableIndices unrolled_to_component_indices(const unsigned int i, const std::integral_constant &) { @@ -2529,7 +2432,7 @@ namespace internal } // namespace internal template -inline TableIndices +constexpr TableIndices SymmetricTensor::unrolled_to_component_indices( const unsigned int i) { @@ -2566,9 +2469,10 @@ SymmetricTensor::serialize(Archive &ar, const unsigned int) * @relatesalso SymmetricTensor */ template -inline SymmetricTensor::type> +DEAL_II_CONSTEXPR inline SymmetricTensor< + rank_, + dim, + typename ProductType::type> operator+(const SymmetricTensor & left, const SymmetricTensor &right) { @@ -2592,9 +2496,10 @@ operator+(const SymmetricTensor & left, * @relatesalso SymmetricTensor */ template -inline SymmetricTensor::type> +DEAL_II_CONSTEXPR inline SymmetricTensor< + rank_, + dim, + typename ProductType::type> operator-(const SymmetricTensor & left, const SymmetricTensor &right) { @@ -2613,7 +2518,7 @@ operator-(const SymmetricTensor & left, * @relatesalso SymmetricTensor */ template -inline Tensor::type> +constexpr Tensor::type> operator+(const SymmetricTensor &left, const Tensor & right) { @@ -2629,7 +2534,7 @@ operator+(const SymmetricTensor &left, * @relatesalso SymmetricTensor */ template -inline Tensor::type> +constexpr Tensor::type> operator+(const Tensor & left, const SymmetricTensor &right) { @@ -2645,7 +2550,7 @@ operator+(const Tensor & left, * @relatesalso SymmetricTensor */ template -inline Tensor::type> +constexpr Tensor::type> operator-(const SymmetricTensor &left, const Tensor & right) { @@ -2661,7 +2566,7 @@ operator-(const SymmetricTensor &left, * @relatesalso SymmetricTensor */ template -inline Tensor::type> +constexpr Tensor::type> operator-(const Tensor & left, const SymmetricTensor &right) { @@ -2684,7 +2589,7 @@ operator-(const Tensor & left, * @author Wolfgang Bangerth, 2005 */ template -inline Number +DEAL_II_CONSTEXPR inline Number determinant(const SymmetricTensor<2, dim, Number> &t) { switch (dim) @@ -2722,7 +2627,7 @@ determinant(const SymmetricTensor<2, dim, Number> &t) * @author Wolfgang Bangerth, 2005 */ template -inline Number +constexpr Number third_invariant(const SymmetricTensor<2, dim, Number> &t) { return determinant(t); @@ -2738,8 +2643,8 @@ third_invariant(const SymmetricTensor<2, dim, Number> &t) * @author Wolfgang Bangerth, 2005 */ template -Number -trace(const SymmetricTensor<2, dim, Number> &d) +DEAL_II_CONSTEXPR Number + trace(const SymmetricTensor<2, dim, Number> &d) { Number t = d.data[0]; for (unsigned int i = 1; i < dim; ++i) @@ -2758,7 +2663,7 @@ trace(const SymmetricTensor<2, dim, Number> &d) * @author Wolfgang Bangerth, 2005 */ template -inline Number +constexpr Number first_invariant(const SymmetricTensor<2, dim, Number> &t) { return trace(t); @@ -2778,7 +2683,7 @@ first_invariant(const SymmetricTensor<2, dim, Number> &t) * @author Wolfgang Bangerth, 2005, 2010 */ template -inline Number +constexpr Number second_invariant(const SymmetricTensor<2, 1, Number> &) { return internal::NumberType::value(0.0); @@ -2806,7 +2711,7 @@ second_invariant(const SymmetricTensor<2, 1, Number> &) * @author Wolfgang Bangerth, 2005, 2010 */ template -inline Number +constexpr Number second_invariant(const SymmetricTensor<2, 2, Number> &t) { return t[0][0] * t[1][1] - t[0][1] * t[0][1]; @@ -2824,7 +2729,7 @@ second_invariant(const SymmetricTensor<2, 2, Number> &t) * @author Wolfgang Bangerth, 2005, 2010 */ template -inline Number +constexpr Number second_invariant(const SymmetricTensor<2, 3, Number> &t) { return (t[0][0] * t[1][1] + t[1][1] * t[2][2] + t[2][2] * t[0][0] - @@ -3243,7 +3148,7 @@ eigenvectors(const SymmetricTensor<2, dim, Number> &T, * @author Wolfgang Bangerth, 2005 */ template -inline SymmetricTensor +constexpr SymmetricTensor transpose(const SymmetricTensor &t) { return t; @@ -3261,7 +3166,7 @@ transpose(const SymmetricTensor &t) * @author Wolfgang Bangerth, 2005 */ template -inline SymmetricTensor<2, dim, Number> +DEAL_II_CONSTEXPR inline SymmetricTensor<2, dim, Number> deviator(const SymmetricTensor<2, dim, Number> &t) { SymmetricTensor<2, dim, Number> tmp = t; @@ -3284,7 +3189,7 @@ deviator(const SymmetricTensor<2, dim, Number> &t) * @author Wolfgang Bangerth, 2005 */ template -inline SymmetricTensor<2, dim, Number> +DEAL_II_CONSTEXPR inline SymmetricTensor<2, dim, Number> unit_symmetric_tensor() { // create a default constructed matrix filled with @@ -3319,7 +3224,7 @@ unit_symmetric_tensor() * @author Wolfgang Bangerth, 2005 */ template -inline SymmetricTensor<2, dim> +DEAL_II_CONSTEXPR inline SymmetricTensor<2, dim> unit_symmetric_tensor() { return unit_symmetric_tensor(); @@ -3342,7 +3247,7 @@ unit_symmetric_tensor() * @author Wolfgang Bangerth, 2005 */ template -inline SymmetricTensor<4, dim, Number> +DEAL_II_CONSTEXPR inline SymmetricTensor<4, dim, Number> deviator_tensor() { SymmetricTensor<4, dim, Number> tmp; @@ -3383,7 +3288,7 @@ deviator_tensor() * @author Wolfgang Bangerth, 2005 */ template -inline SymmetricTensor<4, dim> +DEAL_II_CONSTEXPR inline SymmetricTensor<4, dim> deviator_tensor() { return deviator_tensor(); @@ -3414,7 +3319,7 @@ deviator_tensor() * @author Wolfgang Bangerth, 2005 */ template -inline SymmetricTensor<4, dim, Number> +DEAL_II_CONSTEXPR inline SymmetricTensor<4, dim, Number> identity_tensor() { SymmetricTensor<4, dim, Number> tmp; @@ -3461,7 +3366,7 @@ identity_tensor() * @author Wolfgang Bangerth, 2005 */ template -inline SymmetricTensor<4, dim> +DEAL_II_CONSTEXPR inline SymmetricTensor<4, dim> identity_tensor() { return identity_tensor(); @@ -3480,7 +3385,7 @@ identity_tensor() * @author Jean-Paul Pelteret, 2016 */ template -inline SymmetricTensor<2, dim, Number> +constexpr SymmetricTensor<2, dim, Number> invert(const SymmetricTensor<2, dim, Number> &t) { return internal::SymmetricTensorImplementation::Inverse<2, dim, Number>:: @@ -3501,7 +3406,7 @@ invert(const SymmetricTensor<2, dim, Number> &t) * @author Wolfgang Bangerth, 2005 */ template -inline SymmetricTensor<4, dim, Number> +constexpr SymmetricTensor<4, dim, Number> invert(const SymmetricTensor<4, dim, Number> &t) { return internal::SymmetricTensorImplementation::Inverse<4, dim, Number>:: @@ -3525,7 +3430,7 @@ invert(const SymmetricTensor<4, dim, Number> &t) * @author Wolfgang Bangerth, 2005 */ template -inline SymmetricTensor<4, dim, Number> +DEAL_II_CONSTEXPR inline SymmetricTensor<4, dim, Number> outer_product(const SymmetricTensor<2, dim, Number> &t1, const SymmetricTensor<2, dim, Number> &t2) { @@ -3552,7 +3457,7 @@ outer_product(const SymmetricTensor<2, dim, Number> &t1, * @author Wolfgang Bangerth, 2005 */ template -inline SymmetricTensor<2, dim, Number> +DEAL_II_CONSTEXPR inline SymmetricTensor<2, dim, Number> symmetrize(const Tensor<2, dim, Number> &t) { Number array[(dim * dim + dim) / 2]; @@ -3574,7 +3479,7 @@ symmetrize(const Tensor<2, dim, Number> &t) * @relatesalso SymmetricTensor */ template -inline SymmetricTensor +DEAL_II_CONSTEXPR inline SymmetricTensor operator*(const SymmetricTensor &t, const Number &factor) { SymmetricTensor tt = t; @@ -3592,7 +3497,7 @@ operator*(const SymmetricTensor &t, const Number &factor) * @relatesalso SymmetricTensor */ template -inline SymmetricTensor +constexpr SymmetricTensor operator*(const Number &factor, const SymmetricTensor &t) { // simply forward to the other operator @@ -3627,7 +3532,7 @@ operator*(const Number &factor, const SymmetricTensor &t) * @relatesalso EnableIfScalar */ template -inline SymmetricTensor< +DEAL_II_CONSTEXPR inline SymmetricTensor< rank_, dim, typename ProductType &t, * @relatesalso EnableIfScalar */ template -inline SymmetricTensor< +DEAL_II_CONSTEXPR inline SymmetricTensor< rank_, dim, typename ProductType -inline SymmetricTensor< +DEAL_II_CONSTEXPR inline SymmetricTensor< rank_, dim, typename ProductType &t, * @relatesalso SymmetricTensor */ template -inline SymmetricTensor +DEAL_II_CONSTEXPR inline SymmetricTensor operator*(const SymmetricTensor &t, const double factor) { SymmetricTensor tt = t; @@ -3726,7 +3631,7 @@ operator*(const SymmetricTensor &t, const double factor) * @relatesalso SymmetricTensor */ template -inline SymmetricTensor +DEAL_II_CONSTEXPR inline SymmetricTensor operator*(const double factor, const SymmetricTensor &t) { SymmetricTensor tt = t; @@ -3742,7 +3647,7 @@ operator*(const double factor, const SymmetricTensor &t) * @relatesalso SymmetricTensor */ template -inline SymmetricTensor +DEAL_II_CONSTEXPR inline SymmetricTensor operator/(const SymmetricTensor &t, const double factor) { SymmetricTensor tt = t; @@ -3760,7 +3665,7 @@ operator/(const SymmetricTensor &t, const double factor) * @relatesalso SymmetricTensor */ template -inline typename ProductType::type +constexpr typename ProductType::type scalar_product(const SymmetricTensor<2, dim, Number> & t1, const SymmetricTensor<2, dim, OtherNumber> &t2) { @@ -3778,7 +3683,7 @@ scalar_product(const SymmetricTensor<2, dim, Number> & t1, * @relatesalso Tensor @relatesalso SymmetricTensor */ template -inline typename ProductType::type +DEAL_II_CONSTEXPR inline typename ProductType::type scalar_product(const SymmetricTensor<2, dim, Number> &t1, const Tensor<2, dim, OtherNumber> & t2) { @@ -3801,7 +3706,7 @@ scalar_product(const SymmetricTensor<2, dim, Number> &t1, * @relatesalso Tensor @relatesalso SymmetricTensor */ template -inline typename ProductType::type +constexpr typename ProductType::type scalar_product(const Tensor<2, dim, Number> & t1, const SymmetricTensor<2, dim, OtherNumber> &t2) { @@ -3825,7 +3730,7 @@ scalar_product(const Tensor<2, dim, Number> & t1, * @author Wolfgang Bangerth, 2005 */ template -inline void double_contract( +DEAL_II_CONSTEXPR inline void double_contract( SymmetricTensor<2, 1, typename ProductType::type> &tmp, const SymmetricTensor<4, 1, Number> & t, const SymmetricTensor<2, 1, OtherNumber> & s) @@ -3851,7 +3756,7 @@ inline void double_contract( * @author Wolfgang Bangerth, 2005 */ template -inline void double_contract( +DEAL_II_CONSTEXPR inline void double_contract( SymmetricTensor<2, 1, typename ProductType::type> &tmp, const SymmetricTensor<2, 1, Number> & s, const SymmetricTensor<4, 1, OtherNumber> & t) @@ -3876,7 +3781,7 @@ inline void double_contract( * @relatesalso SymmetricTensor @author Wolfgang Bangerth, 2005 */ template -inline void double_contract( +DEAL_II_CONSTEXPR inline void double_contract( SymmetricTensor<2, 2, typename ProductType::type> &tmp, const SymmetricTensor<4, 2, Number> & t, const SymmetricTensor<2, 2, OtherNumber> & s) @@ -3907,7 +3812,7 @@ inline void double_contract( * @author Wolfgang Bangerth, 2005 */ template -inline void double_contract( +DEAL_II_CONSTEXPR inline void double_contract( SymmetricTensor<2, 2, typename ProductType::type> &tmp, const SymmetricTensor<2, 2, Number> & s, const SymmetricTensor<4, 2, OtherNumber> & t) @@ -3938,7 +3843,7 @@ inline void double_contract( * @author Wolfgang Bangerth, 2005 */ template -inline void double_contract( +DEAL_II_CONSTEXPR inline void double_contract( SymmetricTensor<2, 3, typename ProductType::type> &tmp, const SymmetricTensor<4, 3, Number> & t, const SymmetricTensor<2, 3, OtherNumber> & s) @@ -3970,7 +3875,7 @@ inline void double_contract( * @author Wolfgang Bangerth, 2005 */ template -inline void double_contract( +DEAL_II_CONSTEXPR inline void double_contract( SymmetricTensor<2, 3, typename ProductType::type> &tmp, const SymmetricTensor<2, 3, Number> & s, const SymmetricTensor<4, 3, OtherNumber> & t) @@ -3994,9 +3899,10 @@ inline void double_contract( * @author Wolfgang Bangerth, 2005 */ template -Tensor<1, dim, typename ProductType::type> -operator*(const SymmetricTensor<2, dim, Number> &src1, - const Tensor<1, dim, OtherNumber> & src2) +DEAL_II_CONSTEXPR + Tensor<1, dim, typename ProductType::type> + operator*(const SymmetricTensor<2, dim, Number> &src1, + const Tensor<1, dim, OtherNumber> & src2) { Tensor<1, dim, typename ProductType::type> dest; for (unsigned int i = 0; i < dim; ++i) @@ -4014,7 +3920,7 @@ operator*(const SymmetricTensor<2, dim, Number> &src1, * @author Wolfgang Bangerth, 2005 */ template -Tensor<1, dim, typename ProductType::type> +constexpr Tensor<1, dim, typename ProductType::type> operator*(const Tensor<1, dim, Number> & src1, const SymmetricTensor<2, dim, OtherNumber> &src2) { @@ -4049,15 +3955,14 @@ template -inline DEAL_II_ALWAYS_INLINE +constexpr DEAL_II_ALWAYS_INLINE typename Tensor::type>::tensor_type operator*(const Tensor & src1, - const SymmetricTensor &src2s) + const SymmetricTensor &src2) { - const Tensor src2(src2s); - return src1 * src2; + return src1 * Tensor(src2); } @@ -4087,15 +3992,14 @@ template -inline DEAL_II_ALWAYS_INLINE +constexpr DEAL_II_ALWAYS_INLINE typename Tensor::type>::tensor_type - operator*(const SymmetricTensor &src1s, + operator*(const SymmetricTensor &src1, const Tensor & src2) { - const Tensor src1(src1s); - return src1 * src2; + return Tensor(src1) * src2; } diff --git a/include/deal.II/base/table_indices.h b/include/deal.II/base/table_indices.h index ad66256c67..27188b8463 100644 --- a/include/deal.II/base/table_indices.h +++ b/include/deal.II/base/table_indices.h @@ -51,7 +51,7 @@ public: /** * Default constructor. This constructor sets all indices to zero. */ - TableIndices(); + constexpr TableIndices() = default; /** * Constructor. This is the appropriate constructor for an @@ -61,7 +61,7 @@ public: * This constructor will result in a compiler error if * the template argument @p N is different from one. */ - explicit TableIndices(const std::size_t index0); + constexpr explicit TableIndices(const std::size_t index0); /** * Constructor. This is the appropriate constructor for an @@ -71,7 +71,7 @@ public: * This constructor will result in a compiler error if * the template argument @p N is different from two. */ - TableIndices(const std::size_t index0, const std::size_t index1); + constexpr TableIndices(const std::size_t index0, const std::size_t index1); /** * Constructor. This is the appropriate constructor for an @@ -81,9 +81,9 @@ public: * This constructor will result in a compiler error if * the template argument @p N is different from three. */ - TableIndices(const std::size_t index0, - const std::size_t index1, - const std::size_t index2); + constexpr TableIndices(const std::size_t index0, + const std::size_t index1, + const std::size_t index2); /** * Constructor. This is the appropriate constructor for an @@ -93,10 +93,10 @@ public: * This constructor will result in a compiler error if * the template argument @p N is different from four. */ - TableIndices(const std::size_t index0, - const std::size_t index1, - const std::size_t index2, - const std::size_t index3); + constexpr TableIndices(const std::size_t index0, + const std::size_t index1, + const std::size_t index2, + const std::size_t index3); /** * Constructor. This is the appropriate constructor for an @@ -106,11 +106,11 @@ public: * This constructor will result in a compiler error if * the template argument @p N is different from five. */ - TableIndices(const std::size_t index0, - const std::size_t index1, - const std::size_t index2, - const std::size_t index3, - const std::size_t index4); + constexpr TableIndices(const std::size_t index0, + const std::size_t index1, + const std::size_t index2, + const std::size_t index3, + const std::size_t index4); /** * Convenience constructor that takes up to 9 arguments. It can be used to @@ -140,30 +140,30 @@ public: /** * Read-only access the value of the ith index. */ - std::size_t operator[](const unsigned int i) const; + DEAL_II_CONSTEXPR std::size_t operator[](const unsigned int i) const; /** * Write access the value of the ith index. */ - std::size_t &operator[](const unsigned int i); + DEAL_II_CONSTEXPR std::size_t &operator[](const unsigned int i); /** * Compare two index fields for equality. */ - bool + constexpr bool operator==(const TableIndices &other) const; /** * Compare two index fields for inequality. */ - bool + constexpr bool operator!=(const TableIndices &other) const; /** * Sort the indices in ascending order. While this operation is not very * useful for Table objects, it is used for the SymmetricTensor class. */ - void + DEAL_II_CONSTEXPR void sort(); /** @@ -178,7 +178,7 @@ protected: /** * Store the indices in an array. */ - std::size_t indices[N]; + std::size_t indices[N]{}; }; @@ -186,81 +186,63 @@ protected: /* --------------------- Template and inline functions ---------------- */ -template -TableIndices::TableIndices() -{ - for (unsigned int i = 0; i < N; ++i) - indices[i] = 0; -} - - template -TableIndices::TableIndices(const std::size_t index0) +constexpr TableIndices::TableIndices(const std::size_t index0) + : indices{index0} { static_assert( N == 1, "This constructor is only available for TableIndices<1> objects."); - indices[0] = index0; } template -TableIndices::TableIndices(const std::size_t index0, - const std::size_t index1) +constexpr TableIndices::TableIndices(const std::size_t index0, + const std::size_t index1) + : indices{index0, index1} { static_assert( N == 2, "This constructor is only available for TableIndices<2> objects."); - indices[0] = index0; - indices[1] = index1; } template -TableIndices::TableIndices(const std::size_t index0, - const std::size_t index1, - const std::size_t index2) +constexpr TableIndices::TableIndices(const std::size_t index0, + const std::size_t index1, + const std::size_t index2) + : indices{index0, index1, index2} { static_assert( N == 3, "This constructor is only available for TableIndices<3> objects."); - indices[0] = index0; - indices[1] = index1; - indices[2] = index2; } template -TableIndices::TableIndices(const std::size_t index0, - const std::size_t index1, - const std::size_t index2, - const std::size_t index3) +constexpr TableIndices::TableIndices(const std::size_t index0, + const std::size_t index1, + const std::size_t index2, + const std::size_t index3) + : indices{index0, index1, index2, index3} { static_assert( N == 4, "This constructor is only available for TableIndices<4> objects."); - indices[0] = index0; - indices[1] = index1; - indices[2] = index2; - indices[3] = index3; } template -TableIndices::TableIndices(const std::size_t index0, - const std::size_t index1, - const std::size_t index2, - const std::size_t index3, - const std::size_t index4) +constexpr TableIndices::TableIndices(const std::size_t index0, + const std::size_t index1, + const std::size_t index2, + const std::size_t index3, + const std::size_t index4) + : indices{index0, index1, index2, index3, index4} { static_assert( N == 5, "This constructor is only available for TableIndices<5> objects."); - indices[0] = index0; - indices[1] = index1; - indices[2] = index2; - indices[3] = index3; - indices[4] = index4; } @@ -354,7 +336,8 @@ TableIndices::TableIndices(const std::size_t index0, template -inline std::size_t TableIndices::operator[](const unsigned int i) const +DEAL_II_CONSTEXPR inline std::size_t TableIndices:: + operator[](const unsigned int i) const { AssertIndexRange(i, N); return indices[i]; @@ -362,7 +345,8 @@ inline std::size_t TableIndices::operator[](const unsigned int i) const template -inline std::size_t &TableIndices::operator[](const unsigned int i) +DEAL_II_CONSTEXPR inline std::size_t &TableIndices:: + operator[](const unsigned int i) { AssertIndexRange(i, N); return indices[i]; @@ -370,18 +354,17 @@ inline std::size_t &TableIndices::operator[](const unsigned int i) template -inline bool +constexpr bool TableIndices::operator==(const TableIndices &other) const { - for (unsigned int i = 0; i < N; ++i) - if (indices[i] != other.indices[i]) - return false; - return true; + return std::equal(std::begin(indices), + std::end(indices), + std::begin(other.indices)); } template -inline bool +constexpr bool TableIndices::operator!=(const TableIndices &other) const { return !(*this == other); @@ -389,7 +372,7 @@ TableIndices::operator!=(const TableIndices &other) const template -inline void +DEAL_II_CONSTEXPR inline void TableIndices::sort() { std::sort(std::begin(indices), std::end(indices)); diff --git a/include/deal.II/physics/elasticity/standard_tensors.h b/include/deal.II/physics/elasticity/standard_tensors.h index f154728df2..822d2b0c1e 100644 --- a/include/deal.II/physics/elasticity/standard_tensors.h +++ b/include/deal.II/physics/elasticity/standard_tensors.h @@ -67,7 +67,11 @@ namespace Physics * unit_symmetric_tensor(). If one is to interpret the tensor as a * matrix, then this simply corresponds to the identity matrix. */ - static const SymmetricTensor<2, dim> I; + static DEAL_II_CONSTEXPR const SymmetricTensor<2, dim> I +#ifdef DEAL_II_HAVE_CXX14_CONSTEXPR_CAN_CALL_NONCONSTEXPR + = unit_symmetric_tensor() +#endif + ; /** * The fourth-order referential/spatial unit symmetric tensor @@ -96,7 +100,11 @@ namespace Physics * the fourth-order identity tensor, but rather as a symmetrization * operator. */ - static const SymmetricTensor<4, dim> S; + static DEAL_II_CONSTEXPR const SymmetricTensor<4, dim> S +#ifdef DEAL_II_HAVE_CXX14_CONSTEXPR_CAN_CALL_NONCONSTEXPR + = identity_tensor() +#endif + ; /** * The fourth-order referential/spatial tensor $\mathbf{I} \otimes @@ -108,7 +116,12 @@ namespace Physics * \textrm{trace}\{ \bullet \} \mathbf{I} \, . * @f] */ - static const SymmetricTensor<4, dim> IxI; + static DEAL_II_CONSTEXPR const SymmetricTensor<4, dim> IxI +#ifdef DEAL_II_HAVE_CXX14_CONSTEXPR_CAN_CALL_NONCONSTEXPR + = outer_product(unit_symmetric_tensor(), + unit_symmetric_tensor()) +#endif + ; //@} @@ -153,7 +166,11 @@ namespace Physics * @dealiiWriggersA{47,3.129} * @dealiiHolzapfelA{232,6.105} */ - static const SymmetricTensor<4, dim> dev_P; + static DEAL_II_CONSTEXPR const SymmetricTensor<4, dim> dev_P +#ifdef DEAL_II_HAVE_CXX14_CONSTEXPR_CAN_CALL_NONCONSTEXPR + = deviator_tensor() +#endif + ; /** * Return the fourth-order referential deviatoric tensor, as constructed @@ -214,8 +231,8 @@ namespace Physics * @dealiiHolzapfelA{229,6.83} */ template - static SymmetricTensor<4, dim, Number> - Dev_P(const Tensor<2, dim, Number> &F); + static DEAL_II_CONSTEXPR SymmetricTensor<4, dim, Number> + Dev_P(const Tensor<2, dim, Number> &F); /** * Return the transpose of the fourth-order referential deviatoric tensor, @@ -229,8 +246,8 @@ namespace Physics * @f] */ template - static SymmetricTensor<4, dim, Number> - Dev_P_T(const Tensor<2, dim, Number> &F); + static DEAL_II_CONSTEXPR SymmetricTensor<4, dim, Number> + Dev_P_T(const Tensor<2, dim, Number> &F); //@} @@ -256,7 +273,7 @@ namespace Physics * @dealiiHolzapfelA{228,6.82} */ template - static SymmetricTensor<2, dim, Number> + static constexpr SymmetricTensor<2, dim, Number> ddet_F_dC(const Tensor<2, dim, Number> &F); //@} @@ -281,8 +298,8 @@ namespace Physics * @dealiiWriggersA{76,3.255} */ template - static SymmetricTensor<4, dim, Number> - dC_inv_dC(const Tensor<2, dim, Number> &F); + static DEAL_II_CONSTEXPR SymmetricTensor<4, dim, Number> + dC_inv_dC(const Tensor<2, dim, Number> &F); //@} }; @@ -294,12 +311,12 @@ namespace Physics #ifndef DOXYGEN -// ------------------------- inline functions ------------------------ +// --------------------- inline functions and constants ------------------- template template -inline SymmetricTensor<4, dim, Number> +DEAL_II_CONSTEXPR inline SymmetricTensor<4, dim, Number> Physics::Elasticity::StandardTensors::Dev_P( const Tensor<2, dim, Number> &F) { @@ -325,7 +342,7 @@ Physics::Elasticity::StandardTensors::Dev_P( template template -inline SymmetricTensor<4, dim, Number> +DEAL_II_CONSTEXPR inline SymmetricTensor<4, dim, Number> Physics::Elasticity::StandardTensors::Dev_P_T( const Tensor<2, dim, Number> &F) { @@ -351,7 +368,7 @@ Physics::Elasticity::StandardTensors::Dev_P_T( template template -inline SymmetricTensor<2, dim, Number> +constexpr SymmetricTensor<2, dim, Number> Physics::Elasticity::StandardTensors::ddet_F_dC( const Tensor<2, dim, Number> &F) { @@ -362,7 +379,7 @@ Physics::Elasticity::StandardTensors::ddet_F_dC( template template -inline SymmetricTensor<4, dim, Number> +DEAL_II_CONSTEXPR inline SymmetricTensor<4, dim, Number> Physics::Elasticity::StandardTensors::dC_inv_dC( const Tensor<2, dim, Number> &F) { diff --git a/source/physics/elasticity/standard_tensors.cc b/source/physics/elasticity/standard_tensors.cc index 80d44b3c34..463003aa83 100644 --- a/source/physics/elasticity/standard_tensors.cc +++ b/source/physics/elasticity/standard_tensors.cc @@ -20,6 +20,7 @@ DEAL_II_NAMESPACE_OPEN #ifndef DOXYGEN +# ifndef DEAL_II_HAVE_CXX14_CONSTEXPR_CAN_CALL_NONCONSTEXPR template const SymmetricTensor<2, dim> @@ -43,7 +44,8 @@ template const SymmetricTensor<4, dim> Physics::Elasticity::StandardTensors::dev_P = deviator_tensor(); -#endif // DOXYGEN +# endif // DEAL_II_HAVE_CXX14_CONSTEXPR_CAN_CALL_NONCONSTEXPR +#endif // DOXYGEN // explicit instantiations #include "standard_tensors.inst" -- 2.39.5