Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add to the documentation of SymmetricTensor::operator*. #13196

Merged
merged 1 commit into from
Jan 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
38 changes: 32 additions & 6 deletions include/deal.II/base/symmetric_tensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -885,20 +885,46 @@ class SymmetricTensor
* be a double contraction over two indices, while it is defined as a single
* contraction over only one index for regular <tt>Tensor</tt> 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 <tt>double_contract</tt> 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 <typename OtherNumber>
DEAL_II_CONSTEXPR typename internal::SymmetricTensorAccessors::
double_contraction_result<rank_, 2, dim, Number, OtherNumber>::type
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 <typename OtherNumber>
DEAL_II_CONSTEXPR typename internal::SymmetricTensorAccessors::
Expand Down
26 changes: 20 additions & 6 deletions include/deal.II/base/tensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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
*/
Expand Down