https://mooseframework.inl.gov
CompileTimeDerivativesMaterialInternal.h
Go to the documentation of this file.
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 #include <cstddef>
13 
15 {
16 namespace details
17 {
18 
22 template <std::size_t first, std::size_t second, std::size_t... tail>
23 constexpr bool
25 {
26  if constexpr (first <= second)
27  {
28  if constexpr (sizeof...(tail) == 0)
29  return true;
30  else
31  return is_sorted<second, tail...>();
32  }
33  else
34  return false;
35 }
36 
40 template <std::size_t N>
41 constexpr std::size_t
43 {
44  if constexpr (N == 0)
45  return 1;
46  else if constexpr (N == 1)
47  return 1;
48  else
49  return N * factorial<N - 1>();
50 }
51 
55 template <std::size_t N, std::size_t M>
56 constexpr std::size_t
58 {
59  return factorial<N + M - 1>() / (factorial<N>() * factorial<M - 1>());
60 }
61 
65 template <std::size_t... first, std::size_t... second>
66 constexpr auto
67 merge(std::index_sequence<first...>, std::index_sequence<second...>)
68 {
69  return std::index_sequence<first..., second...>{};
70 }
71 
76 template <std::size_t Nmax, std::size_t first, std::size_t... tail>
77 constexpr auto
78 increment(std::index_sequence<first, tail...>)
79 {
80  if constexpr (first + 1 == Nmax)
81  {
82  if constexpr (sizeof...(tail) == 0)
83  return std::index_sequence<>{};
84  else
85  return merge(std::index_sequence<0>{}, increment<Nmax>(std::index_sequence<tail...>{}));
86  }
87  else
88  return std::index_sequence<first + 1, tail...>{};
89 }
90 
94 template <std::size_t M, std::size_t... N>
95 constexpr std::size_t
96 total_derivatives(std::index_sequence<N...>)
97 {
98  return (num_derivatives<N, M>() + ...);
99 }
100 
105 template <std::size_t... Ns>
106 constexpr auto
107 zeroes(std::index_sequence<Ns...>)
108 {
109  return std::index_sequence<(void(Ns), 0)...>{};
110 }
111 
112 } // namespace details
113 
117 template <std::size_t first, std::size_t second, std::size_t... tail>
118 constexpr bool
119 is_sorted(std::index_sequence<first, second, tail...>)
120 {
121  return details::is_sorted<first, second, tail...>();
122 }
123 
127 template <std::size_t first>
128 constexpr bool
129 is_sorted(std::index_sequence<first>)
130 {
131  return true;
132 }
133 
137 template <std::size_t N, std::size_t M>
138 constexpr std::size_t
140 {
141  // we compute derivatives of orders 0 up to and including N, and subtract 1 for
142  // the 0th order derivative (underived original function)
143  return details::total_derivatives<M>(std::make_index_sequence<N + 1>{}) - 1;
144 }
145 
146 // shim for C++20 std::type_identity
147 template <class T>
149 {
150  using type = T;
151 };
152 
156 template <typename T, std::size_t... Ns>
157 constexpr auto
158 make_tuple_array(std::index_sequence<Ns...>)
159 {
160  // we cannot default construct the tuple, so we wrap it in the type_identity template
162 }
163 
167 template <std::size_t N>
168 constexpr auto
170 {
171  return details::zeroes(std::make_index_sequence<N>{});
172 }
173 
177 template <typename T, std::size_t first, std::size_t... tags>
178 auto
179 take_derivatives(const T & expression, std::index_sequence<first, tags...>)
180 {
181  if constexpr (sizeof...(tags) == 0)
182  return expression.template D<static_cast<CompileTimeDerivatives::CTTag>(first)>();
183  else
184  return take_derivatives(
185  expression.template D<static_cast<CompileTimeDerivatives::CTTag>(first)>(),
186  std::index_sequence<tags...>{});
187 }
188 
189 } // namespace CompileTimeDerivativesMaterialInternal
constexpr auto make_tuple_array(std::index_sequence< Ns... >)
Create a tuple with sizeof...(Ns) entries, containing CTArrayRefs with tags given by the Ns...
constexpr auto increment(std::index_sequence< first, tail... >)
Increment the first number in an index sequence, but roll over into the next number if it reaches Nma...
constexpr std::size_t total_derivatives()
Compute the total number of distinct derivatives for all orders 1 through N.
constexpr auto zeroes(std::index_sequence< Ns... >)
Take an index sequence and return an index sequence of the same length with all entries replaced by z...
auto take_derivatives(const T &expression, std::index_sequence< first, tags... >)
Take all derivatives of expression listed in the index sequence.
constexpr auto merge(std::index_sequence< first... >, std::index_sequence< second... >)
Merge two index sequences into one.
constexpr bool is_sorted()
Check if the given index sequence is sorted ()internal function)
constexpr std::size_t num_derivatives()
Number of distinct order N derivatives of a function with M variables.
constexpr std::size_t total_derivatives(std::index_sequence< N... >)
Compute the total number of distinct derivatives for all orders N.
constexpr auto zeroes()
Create an index sequence containing N zeroes.
constexpr std::size_t factorial()
Compile time evaluation of the factorial of N.
class infix_ostream_iterator if void
Definition: InfixIterator.h:26
constexpr bool is_sorted(std::index_sequence< first, second, tail... >)
Check if the given index sequence is sorted.