12 #include "libmesh/utility.h" 13 #include "libmesh/compare_types.h" 41 using CTCleanType =
typename std::remove_const<typename std::remove_reference<T>::type>::type;
43 template <
typename... Ts>
52 template <
typename T1,
typename T2,
typename... Ts>
79 template <
typename B,
typename E>
80 auto pow(
const B & base,
const E &
exp);
81 template <
int E,
typename B>
101 std::string
print()
const {
return "0"; }
103 template <CTTag dtag>
114 template <
typename T>
122 std::string
print()
const {
return "1"; }
124 template <CTTag dtag>
134 template <
typename T>
140 template <
typename Self>
141 std::string
printParens(
const Self *,
const std::string & op)
const 143 std::string
out = op;
144 if constexpr (T::precedence() > Self::precedence())
145 out +=
"(" +
_arg.print() +
")";
161 template <
typename T>
172 template <CTTag dtag>
181 template <typename T, class = std::enable_if_t<std::is_base_of<CTBase, T>::value>>
191 template <
typename L,
typename R>
200 template <
typename Self>
201 std::string
printParens(
const Self *,
const std::string & op)
const 204 if constexpr (L::precedence() > Self::precedence())
211 if (R::precedence() > Self::precedence() ||
212 (R::precedence() == Self::precedence() && Self::leftAssociative()))
225 template <
typename C,
typename L,
typename R>
231 template <
typename C,
typename L,
typename R>
241 template <CTTag dtag>
247 template <
typename Self>
260 template <
typename C,
typename L,
typename R>
267 template <
typename L,
typename R>
269 min(
const L & left,
const R & right)
274 template <
typename L,
typename R>
276 max(
const L & left,
const R & right)
284 template <CTTag tag,
typename T>
292 template <CTTag dtag>
307 template <CTTag tag = CTNoTag,
typename T>
314 template <
CTTag start_tag,
typename... Values,
CTTag... Tags>
316 makeValuesHelper(
const std::tuple<Values...> & values, std::integer_sequence<CTTag, Tags...>)
318 if constexpr (start_tag ==
CTNoTag)
331 return makeValuesHelper<start_tag>(std::tuple(values...),
332 std::make_integer_sequence<
CTTag,
sizeof...(values)>{});
339 template <CTTag tag,
typename T>
345 std::string
print()
const {
return "[v" + printTag<tag>() +
"]"; }
347 template <CTTag dtag>
350 if constexpr (tag == dtag)
365 template <CTTag tag = CTNoTag,
typename T>
372 template <
CTTag start_tag,
typename... Refs,
CTTag... Tags>
374 makeRefsHelper(
const std::tuple<Refs...> & refs, std::integer_sequence<CTTag, Tags...>)
376 if constexpr (start_tag ==
CTNoTag)
389 return makeRefsHelper<start_tag>(std::tie(refs...),
390 std::make_integer_sequence<
CTTag,
sizeof...(refs)>{});
398 template <CTTag tag,
typename T,
typename I>
406 template <CTTag dtag>
409 if constexpr (tag == dtag)
417 static_assert(!std::is_same_v<ResultType, void>,
418 "Instantiation of CTArrayRef was attempted for a non-subscriptable type.");
428 template <CTTag tag = CTNoTag,
typename T,
typename I>
438 template <
typename L,
typename R>
448 if constexpr (std::is_base_of<CTNullBase, L>::value && std::is_base_of<CTNullBase, R>::value)
451 if constexpr (std::is_base_of<CTNullBase, L>::value)
454 if constexpr (std::is_base_of<CTNullBase, R>::value)
463 template <CTTag dtag>
476 template <
typename L,
typename R>
485 if constexpr (std::is_base_of<CTNullBase, L>::value && std::is_base_of<CTNullBase, R>::value)
488 if constexpr (std::is_base_of<CTNullBase, L>::value)
491 if constexpr (std::is_base_of<CTNullBase, R>::value)
501 template <CTTag dtag>
514 template <
typename L,
typename R>
523 if constexpr (std::is_base_of<CTNullBase, L>::value || std::is_base_of<CTNullBase, R>::value)
526 if constexpr (std::is_base_of<CTOneBase, L>::value && std::is_base_of<CTOneBase, R>::value)
529 if constexpr (std::is_base_of<CTOneBase, L>::value)
532 if constexpr (std::is_base_of<CTOneBase, R>::value)
541 template <CTTag dtag>
554 template <
typename L,
typename R>
563 if constexpr (std::is_base_of<CTOneBase, R>::value)
566 if constexpr (std::is_base_of<CTNullBase, L>::value && !std::is_base_of<CTNullBase, R>::value)
575 template <CTTag dtag>
599 template <CTComparisonEnum C,
typename L,
typename R>
639 template <CTTag dtag>
650 template <
typename L,
typename R>
652 template <
typename L,
typename R>
654 template <
typename L,
typename R>
656 template <
typename L,
typename R>
658 template <
typename L,
typename R>
660 template <
typename L,
typename R>
666 template <
typename L,
typename R>
675 if constexpr (std::is_base_of<CTNullBase, L>::value)
678 if constexpr (std::is_base_of<CTOneBase, L>::value || std::is_base_of<CTNullBase, R>::value)
681 if constexpr (std::is_base_of<CTOneBase, R>::value)
688 template <CTTag dtag>
713 template <
typename B,
typename E>
717 if constexpr (std::is_base_of<CTBase, B>::value && std::is_base_of<CTBase, E>::value)
719 else if constexpr (std::is_base_of<CTBase, E>::value)
721 else if constexpr (std::is_base_of<CTBase, B>::value)
730 template <
typename B,
int E>
739 if constexpr (std::is_base_of<CTNullBase, B>::value)
742 else if constexpr (std::is_base_of<CTOneBase, B>::value || E == 0)
745 else if constexpr (E == 1)
748 else if constexpr (E < 0)
752 return libMesh::Utility::pow<E>(
_arg());
756 template <CTTag dtag>
759 if constexpr (E == 1)
762 else if constexpr (E == 0)
775 template <
int E,
typename B>
779 if constexpr (std::is_base_of<CTBase, B>::value)
789 #define CT_OPERATOR_BINARY(op, OP) \ 790 template <typename L, \ 792 class = std::enable_if_t<std::is_base_of<CTBase, L>::value || \ 793 std::is_base_of<CTBase, R>::value>> \ 794 auto operator op(const L & left, const R & right) \ 798 if constexpr (std::is_base_of<CTBase, L>::value && std::is_base_of<CTBase, R>::value) \ 799 return OP<L, R>(left, right); \ 800 else if constexpr (std::is_base_of<CTBase, L>::value) \ 801 return OP<L, decltype(makeValue(right))>(left, makeValue(right)); \ 802 else if constexpr (std::is_base_of<CTBase, R>::value) \ 803 return OP<decltype(makeValue(left)), R>(makeValue(left), right); \ 805 static_assert(libMesh::always_false<L>, "This should not be instantiated."); \ 824 #define CT_SIMPLE_UNARY_FUNCTION(name, derivative) \ 825 template <typename T> \ 826 class CTF##name : public CTUnary<T> \ 829 CTF##name(T arg) : CTUnary<T>(arg) {} \ 830 auto operator()() const { return std::name(_arg()); } \ 831 template <CTTag dtag> \ 836 std::string print() const { return #name "(" + _arg.print() + ")"; } \ 837 constexpr static int precedence() { return 2; } \ 838 using typename CTUnary<T>::ResultType; \ 839 using CTUnary<T>::_arg; \ 841 template <typename T> \ 842 auto name(const T & v) \ 844 using namespace CompileTimeDerivatives; \ 845 if constexpr (std::is_base_of<CTBase, T>::value) \ 846 return CTF##name(v); \ 848 return CTF##name(makeValue(v)); \ 851 CT_SIMPLE_UNARY_FUNCTION(
exp,
exp(_arg) * _arg.template
D<dtag>())
852 CT_SIMPLE_UNARY_FUNCTION(
log, _arg.template D<dtag>() / _arg)
853 CT_SIMPLE_UNARY_FUNCTION(
sin,
cos(_arg) * _arg.template D<dtag>())
854 CT_SIMPLE_UNARY_FUNCTION(
cos, -1.0 *
sin(_arg) * _arg.template D<dtag>())
855 CT_SIMPLE_UNARY_FUNCTION(tan, (
pow<2>(tan(_arg)) + 1.0) * _arg.template D<dtag>())
856 CT_SIMPLE_UNARY_FUNCTION(
sqrt, 1.0 / (2.0 *
sqrt(_arg)) * _arg.template D<dtag>())
857 CT_SIMPLE_UNARY_FUNCTION(tanh, (1.0 -
pow<2>(tanh(_arg))) * _arg.template D<dtag>())
858 CT_SIMPLE_UNARY_FUNCTION(
sinh,
cosh(_arg) * _arg.template D<dtag>())
859 CT_SIMPLE_UNARY_FUNCTION(
cosh,
sinh(_arg) * _arg.template D<dtag>())
860 CT_SIMPLE_UNARY_FUNCTION(erf,
862 CT_SIMPLE_UNARY_FUNCTION(atan, 1.0 / (
pow<2>(_arg) + 1.0) * _arg.template D<dtag>())
869 #define CT_SIMPLE_BINARY_FUNCTION_CLASS(name, derivative) \ 870 template <typename L, typename R> \ 871 class CTF##name : public CTBinary<L, R> \ 874 CTF##name(L left, R right) : CTBinary<L, R>(left, right) {} \ 875 auto operator()() const { return std::name(_left(), _right()); } \ 876 template <CTTag dtag> \ 881 std::string print() const { return #name "(" + _left.print() + ", " + _right.print() + ")"; } \ 882 constexpr static int precedence() { return 2; } \ 883 using typename CTBinary<L, R>::ResultType; \ 884 using CTBinary<L, R>::_left; \ 885 using CTBinary<L, R>::_right; \ 887 #define CT_SIMPLE_BINARY_FUNCTION_FUNC(name) \ 888 template <typename L, typename R> \ 889 auto name(const L & l, const R & r) \ 891 using namespace CompileTimeDerivatives; \ 892 if constexpr (std::is_base_of<CTBase, L>::value && std::is_base_of<CTBase, R>::value) \ 893 return CTF##name(l, r); \ 894 else if constexpr (std::is_base_of<CTBase, L>::value) \ 895 return CTF##name(l, makeValue(r)); \ 896 else if constexpr (std::is_base_of<CTBase, R>::value) \ 897 return CTF##name(makeValue(l), r); \ 899 return CTF##name(makeValue(l), makeValue(r)); \ 903 (-_left * _right.template
D<dtag>() +
904 _left.template
D<dtag>() * _right) /
906 CT_SIMPLE_BINARY_FUNCTION_FUNC(atan2)
908 template <typename T,
int N,
int M>
912 template <
typename... Ts>
915 static_assert(
sizeof...(a) ==
N * M,
"Invalid number of matrix entries");
917 T &
operator()(std::size_t n, std::size_t m) {
return _data[M * n + m]; }
918 const T &
operator()(std::size_t n, std::size_t m)
const {
return _data[M * n + m]; }
924 template <
typename... Ds>
928 static constexpr
auto N =
sizeof...(Ds);
939 template <
int R, std::size_t... Is>
945 template <std::size_t... Is>
948 const std::array<ResultType, N> d{std::get<Is>(
_derivatives)()...};
949 return ((rowMul<Is>(
is, d) * d[Is]) + ...);
956 template <
CTTag start_tag,
typename T,
CTTag... Tags>
960 return std::make_tuple(f.template D<Tags + start_tag>()...);
967 template <CTTag start_tag,
typename T,
int N>
972 makeStandardDeviationHelper<start_tag>(f, std::make_integer_sequence<CTTag, N>{}),
std::string print() const
std::string print() const
Subtraction operator node.
std::string print() const
ResultType operator()() const
Template class to represent a "zero" value.
static constexpr bool leftAssociative()
left/right associative property should reflect C++ operator properties exactly
ResultType operator()() const
Base class for a binary operator/function.
typename std::remove_const< typename std::remove_reference< T >::type >::type CTCleanType
static constexpr int precedence()
CTSub CT_OPERATOR_BINARY CTMul CTCompareLess CTCompareGreater CTCompareEqual _arg template * sin(_arg) *_arg.template D< dtag >()) CT_SIMPLE_UNARY_FUNCTION(tan
ResultType operator()() const
static constexpr bool leftAssociative()
std::string print() const
CTCompare< CTComparisonEnum::Greater, L, R > CTCompareGreater
CTCleanType< T > ResultType
Multiplication operator node.
std::string print() const
Power operator where both base and exponent can be arbitrary operators.
auto makeRefs(const Ts &... refs)
Helper function to build a list of tagged references to variables.
auto makeStandardDeviation(const T &f, const CTMatrix< Real, N, N > covariance)
Helper function to build a standard deviation object for a function with N parameters with consecutiv...
auto makeValue(T value)
Helper function to build a (potentially tagged) value.
CT_OPERATOR_BINARY(+, CTAdd) CT_OPERATOR_BINARY(-
static constexpr int precedence()
CTCompare< CTComparisonEnum::GreaterEqual, L, R > CTCompareGreaterEqual
std::string print() const
auto makeRef(const T &ref)
Helper function to build a tagged reference to a variable.
std::string print() const
const T & operator()() const
ResultType operator()() const
CTSuperType< typename Ds::ResultType... >::type ResultType
CTSub CT_OPERATOR_BINARY CTMul CTCompareLess CTCompareGreater CTCompareEqual _arg template D< dtag >()/_arg) CT_SIMPLE_UNARY_FUNCTION(sin
auto makeValuesHelper(const std::tuple< Values... > &values, std::integer_sequence< CTTag, Tags... >)
std::string print() const
const T & operator()(std::size_t n, std::size_t m) const
ResultType operator()() const
The following methods are specializations for using the libMesh::Parallel::packed_range_* routines fo...
std::string print() const
static constexpr int precedence()
CTCleanType< T > ResultType
auto max(const L &left, const R &right)
auto makeRefsHelper(const std::tuple< Refs... > &refs, std::integer_sequence< CTTag, Tags... >)
CT_SIMPLE_BINARY_FUNCTION_CLASS(atan2,(-_left *_right.template D< dtag >()+_left.template D< dtag >() *_right)/(pow< 2 >(_left)+pow< 2 >(_right))) CT_SIMPLE_BINARY_FUNCTION_FUNC(atan2) template< typename T
std::array< T, N *M > _data
CTStandardDeviation(std::tuple< Ds... > derivatives, CTMatrix< Real, N, N > covariance)
const CTMatrix< Real, N, N > _covariance
CTCleanType< decltype((static_cast< T >0))[0])> ResultType
std::string print() const
auto evalHelper(const std::index_sequence< Is... > &is) const
auto makeValues(Ts... values)
Helper function to build a list of (potentially tagged) values.
Variable value, referencing a variable of type T.
std::string print() const
int CTTag
Operators representing variable values need to be tagged.
CTSub CT_OPERATOR_BINARY CTMul CTCompareLess CTCompareGreater CTCompareEqual _arg template cos(_arg) *_arg.template D< dtag >()) CT_SIMPLE_UNARY_FUNCTION(cos
static constexpr int precedence()
precedence should reflect C++ operator precedence exactly (higher is binding tighter) ...
Base class for a ternary functions.
Real value(unsigned n, unsigned alpha, unsigned beta, Real x)
ResultType operator()() const
Array variable value, referencing an entry in an indexable container of T types.
CTConditional(C condition, L left, R right)
ResultType rowMul(std::index_sequence< Is... >, const std::array< ResultType, N > &d) const
auto operator-(const T &arg)
Integer exponent power operator.
PetscErrorCode PetscInt const PetscInt IS * is
auto conditional(const C &, const L &, const R &)
static constexpr bool leftAssociative()
CTCompare< CTComparisonEnum::Less, L, R > CTCompareLess
template aliases for the comparison operator nodes
CTBinary(L left, R right)
std::string stringify(const T &t)
conversion to string
Binary comparison operator node.
CTSub CT_OPERATOR_BINARY CTMul CTCompareLess CTCompareGreater CTCompareEqual _arg template sinh(_arg) *_arg.template D< dtag >()) CT_SIMPLE_UNARY_FUNCTION(erf
ResultType operator()() const
CTCompare< CTComparisonEnum::Unequal, L, R > CTCompareUnequal
CTCompare(L left, R right)
CTArrayRef(const T &arr, const I &idx)
auto pow(const B &base, const E &exp)
pow(base, exponent) function overload.
static constexpr bool leftAssociative()
CTSub CT_OPERATOR_BINARY CTMul CTCompareLess CTCompareGreater CTCompareEqual _arg template * sqrt(_arg)) *_arg.template D< dtag >()) CT_SIMPLE_UNARY_FUNCTION(tanh
ResultType operator()() const
std::string printParens(const Self *, const std::string &op) const
static constexpr int precedence()
Base class for a unary operator/function.
static constexpr int precedence()
std::string printParens(const Self *, const std::string &op) const
std::conditional<(sizeof...(Ts) > 0), typename CTSuperType< typename libMesh::CompareTypes< T1, T2 >::supertype, Ts... >::type, typename libMesh::CompareTypes< T1, T2 >::supertype >::type type
CTCompare< CTComparisonEnum::LessEqual, L, R > CTCompareLessEqual
std::string print() const
CTCleanType< T > ResultType
static constexpr int precedence()
libMesh::CompareTypes< typename L::ResultType, typename R::ResultType >::supertype ResultType
std::string print() const
auto makeStandardDeviationHelper(const T &f, std::integer_sequence< CTTag, Tags... >)
std::string print() const
CTSub CT_OPERATOR_BINARY CTMul CTCompareLess CTCompareGreater CTCompareEqual _arg template cosh(_arg) *_arg.template D< dtag >()) CT_SIMPLE_UNARY_FUNCTION(cosh
const std::tuple< Ds... > _derivatives
auto min(const L &left, const R &right)
MooseUnits pow(const MooseUnits &, int)
ResultType operator()() const
ResultType operator()() const
Template class to represent a "one" value.
All compile time derivative system objects derive from this (empty) base class.
void ErrorVector unsigned int
T & operator()(std::size_t n, std::size_t m)
CTSub CT_OPERATOR_BINARY CTMul CTCompareLess CTCompareGreater CTCompareEqual _arg template pow< 2 >(tan(_arg))+1.0) *_arg.template D< dtag >()) CT_SIMPLE_UNARY_FUNCTION(sqrt
CTCompare< CTComparisonEnum::Equal, L, R > CTCompareEqual