13#include <dune/common/hybridutilities.hh>
30 template <
class F,
class Tuple, std::size_t... I>
31 constexpr decltype(
auto) applyAndRemoveRefererenceWrapper(F&& f, Tuple&& t, std::index_sequence<I...>) {
34 std::get<I>(std::forward<Tuple>(t)).get()...);
46 template <
class F,
class Tuple>
47 constexpr decltype(
auto) applyAndRemoveReferenceWrapper(F&& f, Tuple&& t) {
48 return applyAndRemoveRefererenceWrapper(
49 std::forward<F>(f), std::forward<Tuple>(t),
50 std::make_index_sequence<std::tuple_size_v<std::remove_reference_t<Tuple>>>{});
61 auto forwardasReferenceWrapperIfIsReference(T&& t) {
62 if constexpr (std::is_lvalue_reference_v<
decltype(t)>)
78 template <
class Pars,
class Tuple, std::size_t... I>
79 constexpr decltype(
auto) makeTupleOfValuesAndReferences(Tuple&& t, Pars&& p, std::index_sequence<I...>) {
80 return std::make_tuple(
81 forwardasReferenceWrapperIfIsReference(applyAndRemoveReferenceWrapper(std::get<I>(t), p.args))...);
89 template <
typename... Args>
91 std::tuple<std::reference_wrapper<std::remove_reference_t<Args>>...> args;
99 template <
typename... Args>
101 std::tuple<std::reference_wrapper<std::remove_reference_t<Args>>...> args;
113 template <
typename... Args>
115 return Impl::Parameter<Args&&...>{std::forward_as_tuple(std::forward<Args>(args)...)};
125 template <
typename... Args>
127 return Impl::Functions<Args&&...>{std::forward_as_tuple(std::forward<Args>(args)...)};
139 template <
typename... DerivativeArgs,
typename... ParameterArgs>
140 auto initResults(
const Impl::Functions<DerivativeArgs...>& derivativesFunctions,
141 const Impl::Parameter<ParameterArgs...>& parameterI) {
142 return Impl::makeTupleOfValuesAndReferences(
143 derivativesFunctions.args, parameterI,
144 std::make_index_sequence<std::tuple_size_v<std::remove_reference_t<
decltype(derivativesFunctions.args)>>>{});
153 template <
typename TypeListOne,
typename TypeListTwo>
157 [[maybe_unused]]
const TypeListTwo& args) {
158 static_assert(!
sizeof(TypeListOne),
159 "This type should not be instantiated. check that your arguments satisfies the template below");
170 template <
typename... DerivativeArgs,
typename... ParameterArgs>
171 class NonLinearOperator<Impl::Functions<DerivativeArgs...>, Impl::Parameter<ParameterArgs...>> {
173 using FunctionReturnValues
175 using ParameterValues = std::tuple<ParameterArgs...>;
183 using FunctionReturnType = std::tuple_element_t<n, FunctionReturnValues>;
191 using ParameterValue = std::remove_cvref_t<std::tuple_element_t<n, ParameterValues>>;
194 = std::remove_cvref_t<std::tuple_element_t<0, FunctionReturnValues>>;
196 = std::remove_cvref_t<std::tuple_element_t<1, FunctionReturnValues>>;
204 explicit NonLinearOperator(
const Impl::Functions<DerivativeArgs...>& derivativesFunctions,
205 const Impl::Parameter<ParameterArgs...>& parameterI)
206 : derivatives_{derivativesFunctions.args},
207 args_{parameterI.args},
208 derivativesEvaluated_(
initResults(derivativesFunctions, parameterI)) {}
216 Dune::Hybrid::forEach(
217 Dune::Hybrid::integralRange(Dune::index_constant<
sizeof...(DerivativeArgs)>()), [&](
const auto i) {
218 std::get<i>(derivativesEvaluated_) = Impl::applyAndRemoveReferenceWrapper(std::get<i>(derivatives_), args_);
229 std::get<n>(derivativesEvaluated_) = Impl::applyAndRemoveReferenceWrapper(std::get<n>(derivatives_), args_);
239 auto& value()
requires(
sizeof...(DerivativeArgs) > 0) {
return nthDerivative<0>(); }
248 auto& derivative()
requires(
sizeof...(DerivativeArgs) > 1) {
return nthDerivative<1>(); }
257 auto& secondDerivative()
requires(
sizeof...(DerivativeArgs) > 2) {
return nthDerivative<2>(); }
266 auto& nthDerivative()
requires(
sizeof...(DerivativeArgs) > n) {
267 if constexpr (
requires { std::get<n>(derivativesEvaluated_).get(); })
268 return std::get<n>(derivativesEvaluated_).get();
270 return std::get<n>(derivativesEvaluated_);
278 auto& lastParameter() {
return nthParameter<
sizeof...(ParameterArgs) - 1>(); }
284 auto& firstParameter()
requires(
sizeof...(ParameterArgs) > 0) {
return nthParameter<0>(); }
290 auto& secondParameter()
requires(
sizeof...(ParameterArgs) > 1) {
return nthParameter<1>(); }
298 auto& nthParameter()
requires(
sizeof...(ParameterArgs) >= n) {
299 return std::get<n>(args_).get();
308 template <
int... Derivatives>
311 Impl::applyAndRemoveReferenceWrapper(parameter<ParameterArgs...>, args_));
315 using FunctionReturnValuesWrapper = std::tuple<std::conditional_t<
319 std::tuple<std::conditional_t<std::is_reference_v<DerivativeArgs>,
320 std::reference_wrapper<std::remove_reference_t<DerivativeArgs>>,
321 std::remove_reference_t<DerivativeArgs>>...>
323 std::tuple<std::conditional_t<std::is_reference_v<ParameterArgs>,
324 std::reference_wrapper<std::remove_reference_t<ParameterArgs>>,
325 std::remove_reference_t<ParameterArgs>>...>
327 FunctionReturnValuesWrapper derivativesEvaluated_{};
Contains stl-like type traits.
std::invoke_result_t< Fun, Args... > ReturnType
Type trait to obtain the return type of a callable type when given specific arguments.
Definition: traits.hh:63
Definition: simpleassemblers.hh:21
auto functions(Args &&... args)
Creates a Functions object.
Definition: nonlinearoperator.hh:126
auto parameter(Args &&... args)
Creates a Parameter object.
Definition: nonlinearoperator.hh:114
auto initResults(const Impl::Functions< DerivativeArgs... > &derivativesFunctions, const Impl::Parameter< ParameterArgs... > ¶meterI)
Initializes the results for functions and parameters.
Definition: nonlinearoperator.hh:140
Represents a NonLinearOperator class for handling nonlinear operators.
Definition: nonlinearoperator.hh:154
NonLinearOperator(const TypeListOne &derivativesFunctions, const TypeListTwo &args)
Definition: nonlinearoperator.hh:156