From 97d3e0bc01df3d9c4c079189714d8b493251724f Mon Sep 17 00:00:00 2001 From: Jean-Paul Pelteret Date: Sat, 12 Aug 2017 01:04:06 -0600 Subject: [PATCH] Make the SymmetricTensor class more compatible with generic numbers. All stored number initialisation is explicitly performed, and their values are set to a safe default. More operations are templated on a second number type, adding further compatibility between tensors of differing number types. --- include/deal.II/base/symmetric_tensor.h | 152 ++++++++++++++++-------- 1 file changed, 102 insertions(+), 50 deletions(-) diff --git a/include/deal.II/base/symmetric_tensor.h b/include/deal.II/base/symmetric_tensor.h index 2ded82e272..e22d9ed24b 100644 --- a/include/deal.II/base/symmetric_tensor.h +++ b/include/deal.II/base/symmetric_tensor.h @@ -539,7 +539,7 @@ public: /** * Default constructor. Creates a tensor with all entries equal to zero. */ - SymmetricTensor () = default; + SymmetricTensor (); /** * Constructor. Generate a symmetric tensor from a general one. Assumes that @@ -579,13 +579,21 @@ public: explicit SymmetricTensor (const SymmetricTensor &initializer); + /** + * Assignment operator from symmetric tensors with different underlying scalar type. + * This obviously requires that the @p OtherNumber type is convertible to + * @p Number. + */ + template + SymmetricTensor &operator = (const SymmetricTensor &rhs); + /** * This operator assigns a scalar to a tensor. To avoid confusion with what * exactly it means to assign a scalar value to a tensor, zero is the only * value allowed for d, allowing the intuitive notation * t=0 to reset all elements of the tensor to zero. */ - SymmetricTensor &operator = (const Number d); + SymmetricTensor &operator = (const Number &d); /** * Convert the present symmetric tensor into a full tensor with the same @@ -606,35 +614,27 @@ public: /** * Add another tensor. */ - SymmetricTensor &operator += (const SymmetricTensor &); + template + SymmetricTensor &operator += (const SymmetricTensor &); /** * Subtract another tensor. */ - SymmetricTensor &operator -= (const SymmetricTensor &); + template + SymmetricTensor &operator -= (const SymmetricTensor &); /** * Scale the tensor by factor, i.e. multiply all components by * factor. */ - SymmetricTensor &operator *= (const Number factor); - - /** - * Scale the vector by 1/factor. - */ - SymmetricTensor &operator /= (const Number factor); - - /** - * Add two tensors. If possible, you should use operator += instead - * since this does not need the creation of a temporary. - */ - SymmetricTensor operator + (const SymmetricTensor &s) const; + template + SymmetricTensor &operator *= (const OtherNumber &factor); /** - * Subtract two tensors. If possible, you should use operator -= - * instead since this does not need the creation of a temporary. + * Scale the tensor by 1/factor. */ - SymmetricTensor operator - (const SymmetricTensor &s) const; + template + SymmetricTensor &operator /= (const OtherNumber &factor); /** * Unary minus operator. Negate all entries of a tensor. @@ -913,6 +913,17 @@ namespace internal +template +inline +SymmetricTensor::SymmetricTensor () +{ + // Some auto-differentiable numbers need explicit + // zero initialization. + for (unsigned int i=0; i::value(0.0); +} + + template inline SymmetricTensor::SymmetricTensor (const Tensor<2,dim,Number> &t) @@ -984,15 +995,28 @@ SymmetricTensor::SymmetricTensor (const Number (&array) [n_inde +template +template +inline +SymmetricTensor & +SymmetricTensor::operator = (const SymmetricTensor &t) +{ + for (unsigned int i=0; i inline SymmetricTensor & -SymmetricTensor::operator = (const Number d) +SymmetricTensor::operator = (const Number &d) { - Assert (d==Number(), ExcMessage ("Only assignment with zero is allowed")); + Assert (d==internal::NumberType::value(0.0), ExcMessage ("Only assignment with zero is allowed")); (void) d; - data = 0; + data = internal::NumberType::value(0.0); return *this; } @@ -1082,10 +1106,11 @@ SymmetricTensor::operator != template +template inline SymmetricTensor & SymmetricTensor::operator += -(const SymmetricTensor &t) +(const SymmetricTensor &t) { data += t.data; return *this; @@ -1094,10 +1119,11 @@ SymmetricTensor::operator += template +template inline SymmetricTensor & SymmetricTensor::operator -= -(const SymmetricTensor &t) +(const SymmetricTensor &t) { data -= t.data; return *this; @@ -1106,9 +1132,10 @@ SymmetricTensor::operator -= template +template inline SymmetricTensor & -SymmetricTensor::operator *= (const Number d) +SymmetricTensor::operator *= (const OtherNumber &d) { data *= d; return *this; @@ -1117,9 +1144,10 @@ SymmetricTensor::operator *= (const Number d) template +template inline SymmetricTensor & -SymmetricTensor::operator /= (const Number d) +SymmetricTensor::operator /= (const OtherNumber &d) { data /= d; return *this; @@ -1127,30 +1155,6 @@ SymmetricTensor::operator /= (const Number d) -template -inline -SymmetricTensor -SymmetricTensor::operator + (const SymmetricTensor &t) const -{ - SymmetricTensor tmp = *this; - tmp.data += t.data; - return tmp; -} - - - -template -inline -SymmetricTensor -SymmetricTensor::operator - (const SymmetricTensor &t) const -{ - SymmetricTensor tmp = *this; - tmp.data -= t.data; - return tmp; -} - - - template inline SymmetricTensor @@ -2095,6 +2099,54 @@ SymmetricTensor::serialize(Archive &ar, const unsigned int) /* ----------------- Non-member functions operating on tensors. ------------ */ +/** + * Addition of two symmetric tensors of equal rank. The result is another + * SymmetricTensor that has a number type that is compatible with the + * operation. + * + * If possible (e.g. when @p Number and @p OtherNumber are of the same type, + * or if the result of Number() + OtherNumber() is another @p Number), + * you should use operator += instead since this does not require the + * creation of a temporary variable. + * + * @relates SymmetricTensor + */ +template +inline +SymmetricTensor::type> +operator+(const SymmetricTensor &left, + const SymmetricTensor &right) +{ + SymmetricTensor::type> tmp = left; + tmp += right; + return tmp; +} + + +/** + * Subtraction of two symmetric tensors of equal rank. The result is another + * SymmetricTensor that has a number type that is compatible with the + * operation. + * + * If possible (e.g. when @p Number and @p OtherNumber are of the same type, + * or if the result of Number() + OtherNumber() is another @p Number), + * you should use operator += instead since this does not require the + * creation of a temporary variable. + * + * @relates SymmetricTensor + */ +template +inline +SymmetricTensor::type> +operator-(const SymmetricTensor &left, + const SymmetricTensor &right) +{ + SymmetricTensor::type> tmp = left; + tmp -= right; + return tmp; +} + + /** * Addition of a SymmetricTensor and a general Tensor of equal rank. The * result is a general Tensor. -- 2.39.5