From: Wolfgang Bangerth Date: Fri, 7 Jan 2022 18:51:44 +0000 (-0700) Subject: Add to the documentation of SymmetricTensor::operator*. X-Git-Tag: v9.4.0-rc1~634^2 X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b311f59edd286f92871b0b1ba57d778a9b0a645c;p=dealii.git Add to the documentation of SymmetricTensor::operator*. --- diff --git a/include/deal.II/base/symmetric_tensor.h b/include/deal.II/base/symmetric_tensor.h index ceb538ef89..0f0d659d38 100644 --- a/include/deal.II/base/symmetric_tensor.h +++ b/include/deal.II/base/symmetric_tensor.h @@ -885,11 +885,37 @@ public: * be a double contraction over two indices, while it is defined as a single * contraction over only one index for regular Tensor objects. For * symmetric tensors it therefore acts in a way that is commonly denoted by - * a "colon multiplication" in the mathematical literature. + * a "colon multiplication" in the mathematical literature (the two dots of + * the colon suggesting that it is a contraction over two indices), which + * corresponds to a scalar product between tensors. * - * There are global functions double_contract that do the same work - * as this operator, but rather than returning the result as a return value, - * they write it into the first argument to the function. + * It is worth pointing out that this definition of `operator*` between + * symmetric tensors is different to how the (in general non-symmetric) + * Tensor class defines `operator*`, namely as the single-contraction + * product over the last index of the first operand and the first index of + * the second operand. For the double contraction of Tensor objects, + * you will need to use the `double_contract()` function. + * + * To maintain at least a modicum of resemblance between the interfaces + * of Tensor and SymmetricTensor, there are also global functions + * double_contract() for symmetric tensors that then do the same work + * as this operator. However, rather than returning the result as a return + * value, they write it into the first argument to the function in the same + * way as the corresponding functions for the Tensor class do things. + * + * @note The origin of the difference in how `operator*()` is implemented between + * Tensor and SymmetricTensor is that for the former, the product between + * two Tensor objects of same rank and dimension results in another Tensor + * object -- that it, `operator*()` corresponds to the multiplicative group + * action within the group of tensors. On the other hand, there is no + * corresponding multiplicative group action with the set of symmetric + * tensors because, in general, the product of two symmetric tensors is a + * *nonsymmetric* tensor. As a consequence, for a mathematician, it is clear + * that `operator*()` for symmetric tensors must have a different meaning: + * namely the *dot* or *scalar product* that maps two symmetric tensors of + * rank 2 to a scalar. This corresponds to the double-dot (colon) operator + * whose meaning is then extended to the product of any two even-ranked + * symmetric tensors. */ template DEAL_II_CONSTEXPR typename internal::SymmetricTensorAccessors:: @@ -897,8 +923,8 @@ public: operator*(const SymmetricTensor<2, dim, OtherNumber> &s) const; /** - * Contraction over two indices of the present object with the rank-4 - * symmetric tensor given as argument. + * Contraction over the last two indices of the present object with the first + * two indices of the rank-4 symmetric tensor given as argument. */ template DEAL_II_CONSTEXPR typename internal::SymmetricTensorAccessors:: diff --git a/include/deal.II/base/tensor.h b/include/deal.II/base/tensor.h index ba253fc8c0..7261f447d7 100644 --- a/include/deal.II/base/tensor.h +++ b/include/deal.II/base/tensor.h @@ -2282,7 +2282,8 @@ inline constexpr DEAL_II_ALWAYS_INLINE /** - * The dot product (single contraction) for tensors: Return a tensor of rank + * The dot product (single contraction) for tensors. This function return a + * tensor of rank * $(\text{rank}_1 + \text{rank}_2 - 2)$ that is the contraction of the last * index of a tensor @p src1 of rank @p rank_1 with the first index of a * tensor @p src2 of rank @p rank_2: @@ -2295,11 +2296,24 @@ inline constexpr DEAL_II_ALWAYS_INLINE * * @note For the Tensor class, the multiplication operator only performs a * contraction over a single pair of indices. This is in contrast to the - * multiplication operator for SymmetricTensor, which does the double - * contraction. - * - * @note In case the contraction yields a tensor of rank 0 the scalar number - * is returned as an unwrapped number type. + * multiplication operator for SymmetricTensor, for which the corresponding + * `operator*()` performs a double contraction. The origin of the difference in + * how `operator*()` is implemented between Tensor and SymmetricTensor is that + * for the former, the product between two Tensor objects of same rank and + * dimension results in another Tensor object -- that it, `operator*()` + * corresponds to the multiplicative group action within the group of tensors. + * On the other hand, there is no corresponding multiplicative group action with + * the set of symmetric tensors because, in general, the product of two + * symmetric tensors is a *nonsymmetric* tensor. As a consequence, for a + * mathematician, it is clear that `operator*()` for symmetric tensors must have + * a different meaning: namely the *dot* or *scalar product* that maps two + * symmetric tensors of rank 2 to a scalar. This corresponds to the double-dot + * (colon) operator whose meaning is then extended to the product of any two + * even-ranked symmetric tensors. + * + * @note In case the contraction yields a tensor of rank 0, that is, if + * `rank_1==rank_2==1`, then a scalar number is returned as an unwrapped + * number type. * * @relatesalso Tensor */