https://mooseframework.inl.gov
Loading...
Searching...
No Matches
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{
16namespace details
17{
18
22template <std::size_t first, std::size_t second, std::size_t... tail>
23constexpr 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
40template <std::size_t N>
41constexpr 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
55template <std::size_t N, std::size_t M>
56constexpr std::size_t
58{
59 return factorial<N + M - 1>() / (factorial<N>() * factorial<M - 1>());
60}
61
65template <std::size_t... first, std::size_t... second>
66constexpr auto
67merge(std::index_sequence<first...>, std::index_sequence<second...>)
68{
69 return std::index_sequence<first..., second...>{};
70}
71
76template <std::size_t Nmax, std::size_t first, std::size_t... tail>
77constexpr auto
78increment(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
94template <std::size_t M, std::size_t... N>
95constexpr std::size_t
96total_derivatives(std::index_sequence<N...>)
97{
98 return (num_derivatives<N, M>() + ...);
99}
100
105template <std::size_t... Ns>
106constexpr auto
107zeroes(std::index_sequence<Ns...>)
108{
109 return std::index_sequence<(void(Ns), 0)...>{};
110}
111
112} // namespace details
113
117template <std::size_t first, std::size_t second, std::size_t... tail>
118constexpr bool
119is_sorted(std::index_sequence<first, second, tail...>)
120{
121 return details::is_sorted<first, second, tail...>();
122}
123
127template <std::size_t first>
128constexpr bool
129is_sorted(std::index_sequence<first>)
130{
131 return true;
132}
133
137template <std::size_t N, std::size_t M>
138constexpr 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
147template <class T>
149{
150 using type = T;
151};
152
156template <typename T, std::size_t... Ns>
157constexpr auto
158make_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
167template <std::size_t N>
168constexpr auto
170{
171 return details::zeroes(std::make_index_sequence<N>{});
172}
173
177template <typename T, std::size_t first, std::size_t... tags>
178auto
179take_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 zeroes(std::index_sequence< Ns... >)
Take an index sequence and return an index sequence of the same length with all entries replaced by z...
constexpr auto merge(std::index_sequence< first... >, std::index_sequence< second... >)
Merge two index sequences into one.
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 num_derivatives()
Number of distinct order N derivatives of a function with M variables.
constexpr bool is_sorted()
Check if the given index sequence is sorted ()internal function)
constexpr std::size_t factorial()
Compile time evaluation of the factorial of N.
constexpr bool is_sorted(std::index_sequence< first, second, tail... >)
Check if the given index sequence is sorted.
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 zeroes()
Create an index sequence containing N zeroes.
constexpr std::size_t total_derivatives()
Compute the total number of distinct derivatives for all orders 1 through N.
auto take_derivatives(const T &expression, std::index_sequence< first, tags... >)
Take all derivatives of expression listed in the index sequence.
int CTTag
Operators representing variable values need to be tagged.