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

Optimize product of symmetric tensors #15710

Closed
bangerth opened this issue Jul 10, 2023 · 1 comment
Closed

Optimize product of symmetric tensors #15710

bangerth opened this issue Jul 10, 2023 · 1 comment

Comments

@bangerth
Copy link
Member

Internally, SymmetricTensor<2,dim> stores its elements as a Tensor<1,n_independent_components>, and SymmetricTensor<4,dim> stores its elements as a Tensor<2,n_independent_components>, where n_independent_components=dim*(dim-1)/2. In other words, we use something like Voigt notation.

But operator* does not make use of this, but laboriously applies index translations:

template <int rank_, int dim, typename Number>
template <typename OtherNumber>
DEAL_II_HOST DEAL_II_CONSTEXPR inline DEAL_II_ALWAYS_INLINE
  typename internal::SymmetricTensorAccessors::
    double_contraction_result<rank_, 2, dim, Number, OtherNumber>::type
    SymmetricTensor<rank_, dim, Number>::operator*(
      const SymmetricTensor<2, dim, OtherNumber> &s) const
{
  // need to have two different function calls
  // because a scalar and rank-2 tensor are not
  // the same data type (see internal function
  // above)
  return internal::perform_double_contraction<dim, Number, OtherNumber>(data,
                                                                        s.data);
}



template <int rank_, int dim, typename Number>
template <typename OtherNumber>
DEAL_II_HOST DEAL_II_CONSTEXPR inline
  typename internal::SymmetricTensorAccessors::
    double_contraction_result<rank_, 4, dim, Number, OtherNumber>::type
    SymmetricTensor<rank_, dim, Number>::operator*(
      const SymmetricTensor<4, dim, OtherNumber> &s) const
{
  typename internal::SymmetricTensorAccessors::
    double_contraction_result<rank_, 4, dim, Number, OtherNumber>::type tmp;
  tmp.data =
    internal::perform_double_contraction<dim, Number, OtherNumber>(data,
                                                                   s.data);
  return tmp;
}

We should really make this more efficient -- all it takes is a product of two rank-2 and rank-1 tensors :-)

@bangerth
Copy link
Member Author

On second look, the perform_double_contraction() functions are actually about as good as it gets. What I stated above isn't true: It isn't just a matrix-vector or vector-vector product because one has to take into account that some terms of the sum appear twice, but are of course only implemented once.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant