LCOV - code coverage report
Current view: top level - include/utils - SerialAccess.h (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 32 33 97.0 %
Date: 2025-07-17 01:28:37 Functions: 134 219 61.2 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //* This file is part of the MOOSE framework
       2             : //* https://mooseframework.inl.gov
       3             : //*
       4             : //* All rights reserved, see COPYRIGHT for full restrictions
       5             : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
       6             : //*
       7             : //* Licensed under LGPL 2.1, please see LICENSE for details
       8             : //* https://www.gnu.org/licenses/lgpl-2.1.html
       9             : 
      10             : #pragma once
      11             : 
      12             : // MOOSE includes
      13             : #include "Moose.h"
      14             : #include "MooseTypes.h"
      15             : #include "RankTwoTensorForward.h"
      16             : #include "RankFourTensorForward.h"
      17             : 
      18             : #include <tuple>
      19             : 
      20             : namespace Moose
      21             : {
      22             : 
      23             : /**
      24             :  * Serial access requires object data to be stored contiguously. Specialize this template
      25             :  * to support more types.
      26             :  */
      27             : template <typename T>
      28             : struct SerialAccess
      29             : {
      30             :   static_assert(always_false<T>, "Specialize SerialAccess for this type.");
      31             : };
      32             : 
      33             : // Specializations for scalar types
      34             : #define SERIAL_ACCESS_SCALAR(type)                                                                 \
      35             :   template <>                                                                                      \
      36             :   struct SerialAccess<type>                                                                        \
      37             :   {                                                                                                \
      38             :     static type * data(type & obj) { return &obj; }                                                \
      39             :     static constexpr std::size_t size(type &) { return 1u; }                                       \
      40             :     static constexpr std::size_t size() { return 1u; }                                             \
      41             :   }
      42             : 
      43      119941 : SERIAL_ACCESS_SCALAR(Real);
      44       38403 : SERIAL_ACCESS_SCALAR(const Real);
      45           3 : SERIAL_ACCESS_SCALAR(ADReal);
      46           0 : SERIAL_ACCESS_SCALAR(const ADReal);
      47             : 
      48             : // constant size containers
      49             : #define SERIAL_ACCESS_CONST_SIZE(type, dataptr, sizeval)                                           \
      50             :   template <typename T>                                                                            \
      51             :   struct SerialAccess<type<T>>                                                                     \
      52             :   {                                                                                                \
      53             :     static auto * data(type<T> & obj) { return dataptr; }                                          \
      54             :     static constexpr std::size_t size(type<T> &) { return sizeval; }                               \
      55             :     static constexpr std::size_t size() { return sizeval; }                                        \
      56             :   }
      57             : 
      58      119944 : SERIAL_ACCESS_CONST_SIZE(libMesh::VectorValue, &obj(0u), Moose::dim);
      59       99843 : SERIAL_ACCESS_CONST_SIZE(const libMesh::VectorValue, &obj(0u), Moose::dim);
      60      119941 : SERIAL_ACCESS_CONST_SIZE(RankTwoTensorTempl, &obj(0u, 0u), RankTwoTensorTempl<T>::N2);
      61      284160 : SERIAL_ACCESS_CONST_SIZE(const RankTwoTensorTempl, &obj(0u, 0u), RankTwoTensorTempl<T>::N2);
      62      119941 : SERIAL_ACCESS_CONST_SIZE(RankFourTensorTempl, &obj(0u, 0u, 0u, 0u), RankFourTensorTempl<T>::N4);
      63     2496003 : SERIAL_ACCESS_CONST_SIZE(const RankFourTensorTempl,
      64             :                          &obj(0u, 0u, 0u, 0u),
      65             :                          RankFourTensorTempl<T>::N4);
      66             : 
      67             : // dynamic size containers (determining size requires an object instance)
      68             : #define SERIAL_ACCESS_DYNAMIC_SIZE(type, dataptr, sizeval)                                         \
      69             :   template <typename T>                                                                            \
      70             :   struct SerialAccess<type<T>>                                                                     \
      71             :   {                                                                                                \
      72             :     static auto * data(type<T> & obj) { return dataptr; }                                          \
      73             :     static constexpr std::size_t size(type<T> & obj) { return sizeval; }                           \
      74             :   }
      75             : 
      76             : SERIAL_ACCESS_DYNAMIC_SIZE(DenseVector, &obj(0u), obj.size());
      77             : 
      78             : /**
      79             :  * Value type helper (necessary for any type that does not have a value_type
      80             :  * member or where value_type doesn't have a suitable meaning (ADReal)).
      81             :  */
      82             : template <typename T>
      83             : struct SerialAccessValueTypeHelper
      84             : {
      85             :   typedef typename T::value_type value_type;
      86             : };
      87             : template <>
      88             : struct SerialAccessValueTypeHelper<ADReal>
      89             : {
      90             :   typedef ADReal value_type;
      91             : };
      92             : template <>
      93             : struct SerialAccessValueTypeHelper<Real>
      94             : {
      95             :   typedef Real value_type;
      96             : };
      97             : 
      98             : template <typename T>
      99             : class SerialAccessRange
     100             : {
     101             : public:
     102             :   /// Value type of the components of T
     103             :   typedef typename SerialAccessValueTypeHelper<typename std::remove_const<T>::type>::value_type R;
     104             :   /// Value type with the correct constness
     105             :   typedef typename std::conditional<std::is_const_v<T>, const R, R>::type V;
     106             : 
     107             :   class iterator
     108             :   {
     109             :   public:
     110     2265106 :     iterator(V * i) : _i(i) {}
     111             : 
     112     4957367 :     V & operator*() const { return *_i; }
     113             : 
     114     3994807 :     const iterator & operator++()
     115             :     {
     116     3994807 :       ++_i;
     117     3994807 :       return *this;
     118             :     }
     119             : 
     120             :     iterator operator++(int)
     121             :     {
     122             :       iterator returnval(*this);
     123             :       ++_i;
     124             :       return returnval;
     125             :     }
     126             : 
     127     4164800 :     bool operator==(const iterator & j) const { return (_i == j._i); }
     128     4164800 :     bool operator!=(const iterator & j) const { return !(*this == j); }
     129             : 
     130             :   private:
     131             :     V * _i;
     132             :   };
     133             : 
     134     1132553 :   SerialAccessRange(T & obj)
     135     1132553 :     : _begin(SerialAccess<T>::data(obj)),
     136     1132553 :       _end(SerialAccess<T>::data(obj) + SerialAccess<T>::size(obj))
     137             :   {
     138     1132553 :   }
     139             : 
     140      169993 :   iterator begin() const { return _begin; }
     141      169993 :   iterator end() const { return _end; }
     142             : 
     143      962560 :   V & operator[](int i) { return *(&*_begin + i); }
     144             : 
     145             : private:
     146             :   iterator _begin, _end;
     147             : };
     148             : 
     149             : template <typename T>
     150             : SerialAccessRange<T>
     151     1132553 : serialAccess(T & obj)
     152             : {
     153     1132553 :   return SerialAccessRange<T>(obj);
     154             : }
     155             : 
     156             : /// Helper structure to hold a list of types
     157             : template <typename... Ts>
     158             : struct TypeList
     159             : {
     160             :   typedef std::tuple<Ts...> Tuple;
     161             :   typedef std::tuple<Ts *...> PointerTuple;
     162             :   static constexpr std::size_t size = sizeof...(Ts);
     163             : };
     164             : 
     165             : /// Type loop
     166             : template <template <typename, int> class L, int I, typename T, typename... Ts, typename... As>
     167             : void
     168        1152 : typeLoopInternal(TypeList<T, Ts...>, As... args)
     169             : {
     170        1152 :   L<T, I>::apply(args...);
     171             :   if constexpr (sizeof...(Ts) > 0)
     172         864 :     typeLoopInternal<L, I + 1>(TypeList<Ts...>{}, args...);
     173        1152 : }
     174             : 
     175             : /// Type loop
     176             : template <template <typename, int> class L, typename... Ts, typename... As>
     177             : void
     178         288 : typeLoop(TypeList<Ts...>, As... args)
     179             : {
     180         288 :   typeLoopInternal<L, 0>(TypeList<Ts...>{}, args...);
     181         288 : }
     182             : 
     183             : } // namespace Moose;

Generated by: LCOV version 1.14