DotProduct.hpp
Go to the documentation of this file.
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 /// \file
5 /// Defines functions euclidean dot_product and dot_product with a metric
6 
7 #pragma once
8 
9 #include <cstddef>
10 
13 
14 // @{
15 /*!
16  * \ingroup TensorGroup
17  * \brief Compute the Euclidean dot product of two vectors or one forms
18  *
19  * \details
20  * Returns \f$A^a B^b \delta_{ab}\f$ for input vectors \f$A^a\f$ and \f$B^b\f$
21  * or \f$A_a B_b \delta^{ab}\f$ for input one forms \f$A_a\f$ and \f$B_b\f$.
22  */
23 template <typename DataType, typename Index>
26  const Tensor<DataType, Symmetry<1>, index_list<Index>>& vector_a,
27  const Tensor<DataType, Symmetry<1>, index_list<Index>>& vector_b) noexcept {
28  get(*dot_product) = get<0>(vector_a) * get<0>(vector_b);
29  for (size_t d = 1; d < Index::dim; ++d) {
30  get(*dot_product) += vector_a.get(d) * vector_b.get(d);
31  }
32 }
33 
34 template <typename DataType, typename Index>
36  const Tensor<DataType, Symmetry<1>, index_list<Index>>& vector_a,
37  const Tensor<DataType, Symmetry<1>, index_list<Index>>& vector_b) noexcept {
38  Scalar<DataType> dot_product(vector_a.size());
39  ::dot_product(make_not_null(&dot_product), vector_a, vector_b);
40  return dot_product;
41 }
42 // @}
43 
44 // @{
45 /*!
46  * \ingroup TensorGroup
47  * \brief Compute the dot product of a vector and a one form
48  *
49  * \details
50  * Returns \f$A^a B_b \delta_{a}^b\f$ for input vector \f$A^a\f$ and
51  * input one form \f$B_b\f$
52  * or \f$A_a B^b \delta^a_b\f$ for input one form \f$A_a\f$ and
53  * input vector \f$B^b\f$.
54  */
55 template <typename DataType, typename Index>
58  const Tensor<DataType, Symmetry<1>, index_list<Index>>& vector_a,
59  const Tensor<DataType, Symmetry<1>, index_list<change_index_up_lo<Index>>>&
60  vector_b) noexcept {
61  get(*dot_product) = get<0>(vector_a) * get<0>(vector_b);
62  for (size_t d = 1; d < Index::dim; ++d) {
63  get(*dot_product) += vector_a.get(d) * vector_b.get(d);
64  }
65 }
66 
67 template <typename DataType, typename Index>
69  const Tensor<DataType, Symmetry<1>, index_list<Index>>& vector_a,
70  const Tensor<DataType, Symmetry<1>, index_list<change_index_up_lo<Index>>>&
71  vector_b) noexcept {
72  Scalar<DataType> dot_product(vector_a.size());
73  ::dot_product(make_not_null(&dot_product), vector_a, vector_b);
74  return dot_product;
75 }
76 // @}
77 
78 // @{
79 /*!
80  * \ingroup TensorGroup
81  * \brief Compute the dot_product of two vectors or one forms
82  *
83  * \details
84  * Returns \f$g_{ab} A^a B^b\f$, where \f$g_{ab}\f$ is the metric,
85  * \f$A^a\f$ is vector_a, and \f$B^b\f$ is vector_b.
86  * Or, returns \f$g^{ab} A_a B_b\f$ when given one forms \f$A_a\f$
87  * and \f$B_b\f$ with an inverse metric \f$g^{ab}\f$.
88  */
89 template <typename DataType, typename Index>
92  const Tensor<DataType, Symmetry<1>, index_list<Index>>& vector_a,
93  const Tensor<DataType, Symmetry<1>, index_list<Index>>& vector_b,
94  const Tensor<DataType, Symmetry<1, 1>,
95  index_list<change_index_up_lo<Index>,
96  change_index_up_lo<Index>>>& metric) noexcept {
97  get(*dot_product) = get<0>(vector_a) * get<0>(vector_b) * get<0, 0>(metric);
98  for (size_t b = 1; b < Index::dim; ++b) {
99  get(*dot_product) += get<0>(vector_a) * vector_b.get(b) * metric.get(0, b);
100  }
101 
102  for (size_t a = 1; a < Index::dim; ++a) {
103  for (size_t b = 0; b < Index::dim; ++b) {
104  get(*dot_product) += vector_a.get(a) * vector_b.get(b) * metric.get(a, b);
105  }
106  }
107 }
108 
109 template <typename DataType, typename Index>
111  const Tensor<DataType, Symmetry<1>, index_list<Index>>& vector_a,
112  const Tensor<DataType, Symmetry<1>, index_list<Index>>& vector_b,
113  const Tensor<DataType, Symmetry<1, 1>,
114  index_list<change_index_up_lo<Index>,
115  change_index_up_lo<Index>>>& metric) noexcept {
116  Scalar<DataType> dot_product(vector_a.size());
117  ::dot_product(make_not_null(&dot_product), vector_a, vector_b, metric);
118  return dot_product;
119 }
120 // @}
typename detail::SymmetryImpl< std::make_index_sequence< sizeof...(T)>, tmpl::integral_list< std::int32_t, T... > >::type Symmetry
Computes the canonical symmetry from the integers T
Definition: Symmetry.hpp:81
Defines classes for Tensor.
Tensor_detail::TensorIndexType< Index::index_type==IndexType::Spatial ? Index::value :Index::value - 1, Index::ul==UpLo::Up ? UpLo::Lo :UpLo::Up, typename Index::Frame, Index::index_type > change_index_up_lo
Change the TensorIndexType to be covariant if it&#39;s contravariant and vice-versa.
Definition: IndexType.hpp:233
gsl::not_null< T * > make_not_null(T *ptr) noexcept
Construct a not_null from a pointer. Often this will be done as an implicit conversion, but it may be necessary to perform the conversion explicitly when type deduction is desired.
Definition: Gsl.hpp:863
void dot_product(const gsl::not_null< Scalar< DataType > *> dot_product, const Tensor< DataType, Symmetry< 1 >, index_list< Index >> &vector_a, const Tensor< DataType, Symmetry< 1 >, index_list< Index >> &vector_b) noexcept
Compute the Euclidean dot product of two vectors or one forms.
Definition: DotProduct.hpp:24
Tensor< T, Symmetry<>, index_list<> > Scalar
Scalar type.
Definition: TypeAliases.hpp:21
Require a pointer to not be a nullptr
Definition: ConservativeFromPrimitive.hpp:12
Defines make_with_value.