SpECTRE
v2025.03.17
|
Public Types | |
using | contracted_type = typename detail::ContractedType< T, X, Symm, IndexList, ArgsList, NumContractedIndices,(tmpl::size< Symm >::value - NumContractedIndices)/2 > |
Stores internally useful information regarding the contraction. See detail::ContractedType for more details. | |
using | new_type = typename contracted_type::type |
The TensorExpression type that results from performing the contraction. | |
using | type = X |
The type of the data being stored in the result of the expression. | |
using | symmetry = typename new_type::symmetry |
The Symmetry of the result of the expression. | |
using | index_list = typename new_type::index_list |
The list of TensorIndexTypes of the result of the expression. | |
using | args_list = typename new_type::args_list |
The list of generic TensorIndex s of the result of the expression. | |
Public Member Functions | |
TensorContract (const TensorExpression< T, X, Symm, IndexList, ArgsList > &t) | |
template<typename LhsTensor > | |
void | assert_lhs_tensor_not_in_rhs_expression (const gsl::not_null< LhsTensor * > lhs_tensor) const |
Assert that the LHS tensor of the equation does not also appear in this expression's subtree. | |
template<typename LhsTensorIndices , typename LhsTensor > | |
void | assert_lhs_tensorindices_same_in_rhs (const gsl::not_null< LhsTensor * > lhs_tensor) const |
Assert that each instance of the LHS tensor in the RHS tensor expression uses the same generic index order that the LHS uses. More... | |
size_t | get_rhs_tensor_component_size () const |
Get the size of a component from a Tensor in this expression's subtree of the RHS TensorExpression More... | |
decltype(auto) | get (const std::array< size_t, num_tensor_indices > &contracted_multi_index) const |
Return the value of the component of the resultant contracted tensor at a given multi-index. More... | |
template<typename ResultType > | |
decltype(auto) | get_primary (const ResultType &result_component, const std::array< size_t, num_tensor_indices > &contracted_multi_index) const |
Return the value of the component of the resultant contracted tensor at a given multi-index. More... | |
void | evaluate_primary_contraction (type &result_component, const std::array< size_t, num_tensor_indices > &contracted_multi_index, const std::array< size_t, num_uncontracted_tensor_indices > &lowest_multi_index) const |
Successively evaluate the LHS Tensor's result component at each leg of summations within the contraction expression. More... | |
template<typename ResultType > | |
void | evaluate_primary_subtree (ResultType &result_component, const std::array< size_t, num_tensor_indices > &contracted_multi_index) const |
Successively evaluate the LHS Tensor's result component at each leg in this expression's subtree. More... | |
Static Public Member Functions | |
static constexpr std::array< size_t, num_uncontracted_tensor_indices > | get_highest_multi_index_to_sum (const std::array< size_t, num_tensor_indices > &contracted_multi_index) |
Return the highest multi-index between the components being summed in the contraction. More... | |
static constexpr std::array< size_t, num_uncontracted_tensor_indices > | get_lowest_multi_index_to_sum (const std::array< size_t, num_tensor_indices > &contracted_multi_index) |
Return the lowest multi-index between the components being summed in the contraction. More... | |
static std::array< size_t, num_uncontracted_tensor_indices > | get_next_highest_multi_index_to_sum (const std::array< size_t, num_uncontracted_tensor_indices > &uncontracted_multi_index) |
Given the multi-index of one term being summed in the contraction, return the next highest multi-index of a component being summed. More... | |
static std::array< size_t, num_uncontracted_tensor_indices > | get_next_lowest_multi_index_to_sum (const std::array< size_t, num_uncontracted_tensor_indices > &uncontracted_multi_index) |
Given the multi-index of one term being summed in the contraction, return the next lowest multi-index of a component being summed. More... | |
template<size_t Iteration> | |
static decltype(auto) | compute_contraction (const T &t, const std::array< size_t, num_uncontracted_tensor_indices > ¤t_multi_index) |
Computes the value of a component in the resultant contracted tensor. More... | |
template<size_t Iteration> | |
static decltype(auto) | compute_contraction_leg (const T &t, const std::array< size_t, num_uncontracted_tensor_indices > ¤t_multi_index, std::array< size_t, num_uncontracted_tensor_indices > &next_leg_starting_multi_index) |
Computes the result of an internal leg of the contraction. More... | |
template<size_t Iteration> | |
static decltype(auto) | compute_contraction_primary (const T &t, const type &result_component, const std::array< size_t, num_uncontracted_tensor_indices > ¤t_multi_index) |
Computes the value of a component in the resultant contracted tensor. More... | |
Static Public Attributes | |
static constexpr size_t | num_tensor_indices = NumContractedIndices |
The number of tensor indices in the result of the expression. | |
static constexpr size_t | num_uncontracted_tensor_indices |
The number of tensor indices in the operand expression being contracted. More... | |
static constexpr size_t | num_indices_to_contract |
The number of tensor indices in the operand expression that will be contracted. More... | |
static constexpr size_t | num_contracted_index_pairs |
The number of tensor index pairs in the operand expression that will be contracted. More... | |
static constexpr std::array< size_t, NumContractedIndices > | index_transformation |
Mapping from the positions of indices in the resultant contracted tensor to their positions in the operand uncontracted tensor. More... | |
static constexpr std::array< std::pair< size_t, size_t >, num_contracted_index_pairs > | contracted_index_pair_positions |
Positions of the index pairs in the operand uncontracted tensor that we wish to contract. More... | |
static constexpr std::array< std::pair< size_t, size_t >, num_contracted_index_pairs > | contracted_index_first_values |
First concrete values of contracted indices to sum. This is to handle cases when we have generic spatial TensorIndex s used for spacetime indices, as the first concrete index value to contract will be 1 (first spatial index) instead of 0 (the time index). Contracted index pairs will have different "starting" concrete indices when one index in the pair is a spatial spacetime index and the other is not. More... | |
static constexpr std::array< size_t, num_uncontracted_tensor_indices > | uncontracted_index_dims = contracted_type::uncontracted_index_dims |
The dimensions of the indices in the uncontracted operand expression. | |
static constexpr size_t | num_terms_summed = contracted_type::num_terms_summed |
The number of terms to sum for this expression's contraction. | |
static constexpr size_t | num_ops_left_child |
The number of arithmetic tensor operations done in the subtree for the left operand. More... | |
static constexpr size_t | num_ops_right_child = 0 |
The number of arithmetic tensor operations done in the subtree for the right operand. This is 0 because this expression represents a unary operation. | |
static constexpr size_t | num_ops_subtree = num_ops_left_child |
The total number of arithmetic tensor operations done in this expression's whole subtree. | |
static constexpr size_t | height_relative_to_closest_tensor_leaf_in_subtree |
The height of this expression's node in the expression tree relative to the closest TensorAsExpression leaf in its subtree. More... | |
static constexpr bool | is_primary_end = T::is_primary_start |
If on the primary path, whether or not the expression is an ending point of a leg. | |
static constexpr size_t | num_ops_to_evaluate_primary_left_child |
If on the primary path, this is the remaining number of arithmetic tensor operations that need to be done in the subtree of the child along the primary path, given that we will have already computed the whole subtree at the next lowest leg's starting point. More... | |
static constexpr size_t | num_ops_to_evaluate_primary_right_child |
If on the primary path, this is the remaining number of arithmetic tensor operations that need to be done in the right operand's subtree. No splitting is currently done, so this is just num_ops_right_child . More... | |
static constexpr size_t | num_ops_to_evaluate_primary_subtree |
If on the primary path, this is the remaining number of arithmetic tensor operations that need to be done for this expression's subtree, given that we will have already computed the subtree at the next lowest leg's starting point. More... | |
static constexpr bool | is_primary_start |
If on the primary path, whether or not the expression is a starting point of a leg. More... | |
static constexpr bool | primary_child_subtree_contains_primary_start |
If on the primary path, whether or not the expression's child along the primary path is a subtree that contains a starting point of a leg along the primary path. More... | |
static constexpr bool | primary_subtree_contains_primary_start |
If on the primary path, whether or not this subtree contains a starting point of a leg along the primary path. More... | |
static constexpr size_t | num_ops_subexpression = T::num_ops_subtree |
Number of arithmetic tensor operations done in the subtree of the operand expression being contracted. | |
static constexpr size_t | leg_length |
In the subtree for this contraction, how many terms we sum together for each leg of the contraction. More... | |
static constexpr size_t | num_full_legs |
After dividing up the contraction subtree into legs, the number of legs whose length is equal to leg_length More... | |
static constexpr size_t | last_leg_length |
After dividing up the contraction subtree into legs of even length, the number of terms we still have left to sum. More... | |
static constexpr bool | evaluate_terms_separately = leg_length == 0 |
When evaluating along a primary path, whether each term's subtrees should be evaluated separately. Since DataVector expression runtime scales poorly with increased number of operations, evaluating individual terms' subtrees separately like this is beneficial when each term, itself, involves many tensor operations. | |
|
inline |
Assert that each instance of the LHS tensor in the RHS tensor expression uses the same generic index order that the LHS uses.
LhsTensorIndices | the list of generic TensorIndex s of the LHS result Tensor being computed |
lhs_tensor | the LHS result Tensor being computed |
|
inlinestatic |
Computes the value of a component in the resultant contracted tensor.
The contraction is computed by recursively adding up each component in the summation, across all index pairs being contracted in the operand expression. This function is called Iteration = num_terms_summed
times, once for each uncontracted tensor component being summed. It should externally be called for the first time with Iteration == 0
and current_multi_index == <highest multi index to sum>
(see get_next_highest_multi_index_to_sum
for details).
In performing the recursive summation, the recursion is specifically done "to the left," in that this function returns compute_contraction(next index) + get(this_index)
as opposed to get(this_index) + compute_contraction
. Benchmarking has shown that increased breadth in an equation's expression tree can slow down runtime. By "recursing left" here, we minimize breadth in the overall tree for an equation, as both AddSub
addition and OuterProduct
(other expressions with two children) make efforts to make their operands with larger subtrees be their left operand.
Iteration | the nth term to sum, where n is between [0, num_terms_summed) |
t | the expression contained within this contraction expression |
current_multi_index | the multi-index of the uncontracted tensor component to retrieve |
Returns: the value of a component of the resulant contracted tensor
|
inlinestatic |
Computes the result of an internal leg of the contraction.
This function differs from compute_contraction
and compute_contraction_primary
in that it only computes one leg of the whole contraction, as opposed to the whole contraction.
The leg being summed is defined by the current_multi_index
and Iteration
passed in from the inital external call: consecutive terms will be summed until the base case Iteration == 0
is reached.
Iteration | the nth term in the leg to sum, where n is between [0, leg_length) |
t | the expression contained within this contraction expression |
current_multi_index | the multi-index of the uncontracted tensor component to retrieve as part of this leg's summation |
next_leg_starting_multi_index | in the final iteration, the multi-index to update to be the next leg's starting multi-index |
Returns: the result of summing up the terms in the given leg
|
inlinestatic |
Computes the value of a component in the resultant contracted tensor.
First see compute_contraction
for details on basic functionality.
This function differs from compute_contraction
in that it takes into account whether we have already computed part of the result component at a lower subtree. In recursively computing this contraction, the current result component will be substituted in for the most recent (highest) subtree below it that has already been evaluated.
Iteration | the nth term to sum, where n is between [0, num_terms_summed) |
t | the expression contained within this contraction expression |
result_component | the LHS tensor component to evaluate |
current_multi_index | the multi-index of the uncontracted tensor component to retrieve |
Returns: the value of a component of the resulant contracted tensor
|
inline |
Successively evaluate the LHS Tensor's result component at each leg of summations within the contraction expression.
This function takes into account whether we have already computed part of the result component at a lower subtree. In recursively computing this contraction, the current result component will be substituted in for the most recent (highest) subtree below it that has already been evaluated.
result_component | the LHS tensor component to evaluate |
contracted_multi_index | the multi-index of the component of the contracted result tensor to evaluate |
lowest_multi_index | the lowest multi-index between the components being summed in the contraction (see get_lowest_multi_index_to_sum ) |
|
inline |
Successively evaluate the LHS Tensor's result component at each leg in this expression's subtree.
This function takes into account whether we have already computed part of the result component at a lower subtree. In recursively computing this contraction, the current result component will be substituted in for the most recent (highest) subtree below it that has already been evaluated.
If this contraction expression is the beginning of a leg, evaluate_primary_contraction
is called to evaluate each individual leg of summations within the contraction.
result_component | the LHS tensor component to evaluate |
contracted_multi_index | the multi-index of the component of the contracted result tensor to evaluate |
|
inline |
Return the value of the component of the resultant contracted tensor at a given multi-index.
contracted_multi_index | the multi-index of the resultant contracted tensor component to retrieve |
Returns: the value of the component at contracted_multi_index
in the resultant contracted tensor
|
inlinestaticconstexpr |
Return the highest multi-index between the components being summed in the contraction.
Example: We have expression R(ti::A, ti::b, ti::a)
to represent the contraction contracted_multi_index
is {1}
, which represents {2, 1, 2}
.
contracted_multi_index | the multi-index of a component of the contracted expression |
Returns: the highest multi-index between the components being summed in the contraction
|
inlinestaticconstexpr |
Return the lowest multi-index between the components being summed in the contraction.
Example: We have expression R(ti::A, ti::b, ti::a)
to represent the contraction contracted_multi_index
is {1}
, which represents {0, 1, 0}
.
contracted_multi_index | the multi-index of a component of the contracted expression |
Returns: the lowest multi-index between the components being summed in the contraction
|
inlinestatic |
Given the multi-index of one term being summed in the contraction, return the next highest multi-index of a component being summed.
What is meant by "next highest" is implementation defined, but generally means, of the components being summed, return the multi-index that results from lowering one of the contracted index pairs' values by one.
Example: We have expression R(ti::A, ti::b, ti::a)
to represent the contraction uncontracted_multi_index
is {1, 1, 1}
, then the "next highest" multi-index is the result of lowering the values of the
{0, 1, 0}
.Note: this function should perform the inverse functionality of get_next_highest_multi_index_to_sum
. If the implementation of this function or the other changes what is meant by "next highest" or "next
lowest," the other function should be updated in accordance.
uncontracted_multi_index | the multi-index of one of the components of the uncontracted operand expression to sum |
Returns: the next highest multi-index between the components being summed in the contraction
|
inlinestatic |
Given the multi-index of one term being summed in the contraction, return the next lowest multi-index of a component being summed.
What is meant by "next lowest" is implementation defined, but generally means, of the components being summed, return the multi-index that results from raising one of the contracted index pairs' values by one.
Example: We have expression R(ti::A, ti::b, ti::a)
to represent the contraction uncontracted_multi_index
is {1, 1, 1}
, then the "next lowest" multi-index is the result of raising the values of the
{2, 1, 2}
.Note: this function should perform the inverse functionality of get_next_lowest_multi_index_to_sum
. If the implementation of this function or the other changes what is meant by "next highest" or "next
lowest," the other function should be updated in accordance.
uncontracted_multi_index | the multi-index of one of the components of the uncontracted operand expression to sum |
Returns: the next lowest multi-index between the components being summed in the contraction
|
inline |
Return the value of the component of the resultant contracted tensor at a given multi-index.
This function differs from get
in that it takes into account whether we have already computed part of the result component at a lower subtree. In recursively computing this contraction, the current result component will be substituted in for the most recent (highest) subtree below it that has already been evaluated.
result_component | the LHS tensor component to evaluate |
contracted_multi_index | the multi-index of the resultant contracted tensor component to retrieve |
Returns: the value of the component at contracted_multi_index
in the resultant contracted tensor
|
inline |
|
inlinestaticconstexpr |
First concrete values of contracted indices to sum. This is to handle cases when we have generic spatial TensorIndex
s used for spacetime indices, as the first concrete index value to contract will be 1 (first spatial index) instead of 0 (the time index). Contracted index pairs will have different "starting" concrete indices when one index in the pair is a spatial spacetime index and the other is not.
|
inlinestaticconstexpr |
Positions of the index pairs in the operand uncontracted tensor that we wish to contract.
|
staticconstexpr |
The height of this expression's node in the expression tree relative to the closest TensorAsExpression
leaf in its subtree.
|
inlinestaticconstexpr |
Mapping from the positions of indices in the resultant contracted tensor to their positions in the operand uncontracted tensor.
|
staticconstexpr |
If on the primary path, whether or not the expression is a starting point of a leg.
|
staticconstexpr |
After dividing up the contraction subtree into legs of even length, the number of terms we still have left to sum.
|
staticconstexpr |
In the subtree for this contraction, how many terms we sum together for each leg of the contraction.
|
staticconstexpr |
The number of tensor index pairs in the operand expression that will be contracted.
|
staticconstexpr |
After dividing up the contraction subtree into legs, the number of legs whose length is equal to leg_length
|
staticconstexpr |
The number of tensor indices in the operand expression that will be contracted.
|
staticconstexpr |
The number of arithmetic tensor operations done in the subtree for the left operand.
|
staticconstexpr |
If on the primary path, this is the remaining number of arithmetic tensor operations that need to be done in the subtree of the child along the primary path, given that we will have already computed the whole subtree at the next lowest leg's starting point.
|
staticconstexpr |
If on the primary path, this is the remaining number of arithmetic tensor operations that need to be done in the right operand's subtree. No splitting is currently done, so this is just num_ops_right_child
.
|
staticconstexpr |
If on the primary path, this is the remaining number of arithmetic tensor operations that need to be done for this expression's subtree, given that we will have already computed the subtree at the next lowest leg's starting point.
|
staticconstexpr |
The number of tensor indices in the operand expression being contracted.
|
staticconstexpr |
If on the primary path, whether or not the expression's child along the primary path is a subtree that contains a starting point of a leg along the primary path.
|
staticconstexpr |
If on the primary path, whether or not this subtree contains a starting point of a leg along the primary path.