SpECTRE Documentation Coverage Report
Current view: top level - DataStructures/Tensor/Expressions - NumberAsExpression.hpp Hit Total Coverage
Commit: 37c384043430860f87787999aa7399d01bb3d213 Lines: 21 28 75.0 %
Date: 2024-04-20 02:24:02
Legend: Lines: hit not hit

          Line data    Source code
       1           0 : // Distributed under the MIT License.
       2             : // See LICENSE.txt for details.
       3             : 
       4             : #pragma once
       5             : 
       6             : #include <array>
       7             : #include <cstddef>
       8             : #include <limits>
       9             : 
      10             : #include "DataStructures/Tensor/Expressions/DataTypeSupport.hpp"
      11             : #include "DataStructures/Tensor/Expressions/TensorExpression.hpp"
      12             : #include "Utilities/ForceInline.hpp"
      13             : #include "Utilities/TMPL.hpp"
      14             : 
      15             : namespace tenex {
      16             : /// \ingroup TensorExpressionsGroup
      17             : /// \brief Marks a class as being a `NumberAsExpression<DataType>`
      18             : ///
      19             : /// \details
      20             : /// The empty base class provides a simple means for checking if a type is a
      21             : /// `NumberAsExpression<DataType>`.
      22           1 : struct MarkAsNumberAsExpression {};
      23             : 
      24             : /// \ingroup TensorExpressionsGroup
      25             : /// \brief Defines an expression representing a number
      26             : ///
      27             : /// \details
      28             : /// For details on aliases and members defined in this class, as well as general
      29             : /// `TensorExpression` terminology used in its members' documentation, see
      30             : /// documentation for `TensorExpression`.
      31             : template <typename DataType>
      32           1 : struct NumberAsExpression
      33             :     : public TensorExpression<NumberAsExpression<DataType>, DataType,
      34             :                               tmpl::list<>, tmpl::list<>, tmpl::list<>>,
      35             :       MarkAsNumberAsExpression {
      36             :   static_assert(detail::is_supported_number_datatype_v<DataType>,
      37             :                 "TensorExpressions currently only support numeric terms whose "
      38             :                 "type is double or std::complex<double>. It is possible to add "
      39             :                 "support for more numeric types.");
      40             : 
      41             :   // === Index properties ===
      42             :   /// The type of the data being stored in the result of the expression
      43           1 :   using type = DataType;
      44             :   /// The list of \ref SpacetimeIndex "TensorIndexType"s of the result of the
      45             :   /// expression
      46           1 :   using symmetry = tmpl::list<>;
      47             :   /// The list of \ref SpacetimeIndex "TensorIndexType"s of the result of the
      48             :   /// expression
      49           1 :   using index_list = tmpl::list<>;
      50             :   /// The list of generic `TensorIndex`s of the result of the expression
      51           1 :   using args_list = tmpl::list<>;
      52             :   /// The number of tensor indices in the result of the expression
      53           1 :   static constexpr auto num_tensor_indices = 0;
      54             : 
      55             :   // === Expression subtree properties ===
      56             :   /// The number of arithmetic tensor operations done in the subtree for the
      57             :   /// left operand, which is 0 because this is a leaf expression
      58           1 :   static constexpr size_t num_ops_left_child = 0;
      59             :   /// The number of arithmetic tensor operations done in the subtree for the
      60             :   /// right operand, which is 0 because this is a leaf expression
      61           1 :   static constexpr size_t num_ops_right_child = 0;
      62             :   /// The total number of arithmetic tensor operations done in this expression's
      63             :   /// whole subtree, which is 0 because this is a leaf expression
      64           1 :   static constexpr size_t num_ops_subtree = 0;
      65             :   /// The height of this expression's node in the expression tree relative to
      66             :   /// the closest `TensorAsExpression` leaf in its subtree. Because this
      67             :   /// expression type is leaf, the height for this type is set to the maximum
      68             :   /// `size_t` value to encode a sense of maximal height.
      69           1 :   static constexpr size_t height_relative_to_closest_tensor_leaf_in_subtree =
      70             :       std::numeric_limits<size_t>::max();
      71             : 
      72             :   // === Properties for splitting up subexpressions along the primary path ===
      73             :   // These definitions only have meaning if this expression actually ends up
      74             :   // being along the primary path that is taken when evaluating the whole tree.
      75             :   // See documentation for `TensorExpression` for more details.
      76             :   /// If on the primary path, whether or not the expression is an ending point
      77             :   /// of a leg
      78           1 :   static constexpr bool is_primary_end = true;
      79             :   /// If on the primary path, this is the remaining number of arithmetic tensor
      80             :   /// operations that need to be done in the subtree of the child along the
      81             :   /// primary path, given that we will have already computed the whole subtree
      82             :   /// at the next lowest leg's starting point. This is just 0 because this
      83             :   /// expression is a leaf.
      84           1 :   static constexpr size_t num_ops_to_evaluate_primary_left_child = 0;
      85             :   /// If on the primary path, this is the remaining number of arithmetic tensor
      86             :   /// operations that need to be done in the right operand's subtree. This is
      87             :   /// just 0 because this expression is a leaf.
      88           1 :   static constexpr size_t num_ops_to_evaluate_primary_right_child = 0;
      89             :   /// If on the primary path, this is the remaining number of arithmetic tensor
      90             :   /// operations that need to be done for this expression's subtree, given that
      91             :   /// we will have already computed the subtree at the next lowest leg's
      92             :   /// starting point. This is just 0 because this expression is a leaf.
      93           1 :   static constexpr size_t num_ops_to_evaluate_primary_subtree = 0;
      94             :   /// If on the primary path, whether or not the expression is a starting point
      95             :   /// of a leg
      96           1 :   static constexpr bool is_primary_start = false;
      97             :   /// If on the primary path, whether or not the expression's child along the
      98             :   /// primary path is a subtree that contains a starting point of a leg along
      99             :   /// the primary path. This is always falls because this expression is a leaf.
     100           1 :   static constexpr bool primary_child_subtree_contains_primary_start = false;
     101             :   /// If on the primary path, whether or not this subtree contains a starting
     102             :   /// point of a leg along the primary path
     103           1 :   static constexpr bool primary_subtree_contains_primary_start =
     104             :       is_primary_start;
     105             : 
     106           0 :   NumberAsExpression(const type& number) : number_(number) {}
     107           0 :   ~NumberAsExpression() override = default;
     108             : 
     109             :   // This expression does not represent a tensor, nor does it have any children,
     110             :   // so we should never need to assert that the LHS `Tensor` is not equal to the
     111             :   // number stored by this expression
     112             :   template <typename LhsTensor>
     113           0 :   void assert_lhs_tensor_not_in_rhs_expression(
     114             :       const gsl::not_null<LhsTensor*>) const = delete;
     115             :   // This expression does not represent a tensor, nor does it have any children,
     116             :   // so we should never need to assert that instances of the LHS Tensor in this
     117             :   // expression's subtree have the same generic index order
     118             :   template <typename LhsTensorIndices, typename LhsTensor>
     119           0 :   void assert_lhs_tensorindices_same_in_rhs(
     120             :       const gsl::not_null<LhsTensor*> lhs_tensor) const = delete;
     121             :   // This expression is a non-`Tensor` leaf, so we should never try to get the
     122             :   // size of a `Tensor` component from this expression.
     123           0 :   size_t get_rhs_tensor_component_size() const = delete;
     124             : 
     125             :   /// \brief Returns the number represented by the expression
     126             :   ///
     127             :   /// \return the number represented by this expression
     128             :   SPECTRE_ALWAYS_INLINE type
     129           1 :   get(const std::array<size_t, num_tensor_indices>& /*multi_index*/) const {
     130             :     return number_;
     131             :   }
     132             : 
     133             :   /// \brief Returns the number represented by the expression
     134             :   ///
     135             :   /// \return the number represented by this expression
     136             :   template <typename ResultType>
     137           1 :   SPECTRE_ALWAYS_INLINE type get_primary(
     138             :       const ResultType& /*result_component*/,
     139             :       const std::array<size_t, num_tensor_indices>& /*multi_index*/) const {
     140             :     return number_;
     141             :   }
     142             : 
     143             :   // This expression is a leaf and therefore will never be the start of a leg
     144             :   // to evaluate in a split tree, which is enforced by
     145             :   // `is_primary_start == false`. Therefore, this function should never be
     146             :   // called on this expression type.
     147             :   template <typename ResultType>
     148           0 :   void evaluate_primary_subtree(
     149             :       ResultType&,
     150             :       const std::array<size_t, num_tensor_indices>&) const = delete;
     151             : 
     152             :  private:
     153             :   /// Number represented by this expression
     154           1 :   type number_;
     155             : };
     156             : }  // namespace tenex

Generated by: LCOV version 1.14