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...>) {
32 return std::invoke(std::forward<F>(f),
33 std::get<I>(std::forward<Tuple>(t)).get()...);
45 template <
class F,
class Tuple>
46 constexpr decltype(
auto) applyAndRemoveReferenceWrapper(F&& f, Tuple&& t) {
47 return applyAndRemoveRefererenceWrapper(
48 std::forward<F>(f), std::forward<Tuple>(t),
49 std::make_index_sequence<std::tuple_size_v<std::remove_reference_t<Tuple>>>{});
60 auto forwardasReferenceWrapperIfIsReference(T&& t) {
61 if constexpr (std::is_lvalue_reference_v<
decltype(t)>)
77 template <
class Pars,
class Tuple, std::size_t... I>
78 constexpr decltype(
auto) makeTupleOfValuesAndReferences(Tuple&& t, Pars&& p, std::index_sequence<I...>) {
79 return std::make_tuple(
80 forwardasReferenceWrapperIfIsReference(applyAndRemoveReferenceWrapper(std::get<I>(t), p.args))...);
88 template <
typename... Args>
91 std::tuple<std::reference_wrapper<std::remove_reference_t<Args>>...> args;
99 template <
typename... Args>
102 std::tuple<std::reference_wrapper<std::remove_reference_t<Args>>...> args;
114template <
typename... Args>
116 return Impl::Parameter<Args&&...>{std::forward_as_tuple(std::forward<Args>(args)...)};
126template <
typename... Args>
128 return Impl::Functions<Args&&...>{std::forward_as_tuple(std::forward<Args>(args)...)};
140template <
typename... DerivativeArgs,
typename... ParameterArgs>
141auto initResults(
const Impl::Functions<DerivativeArgs...>& derivativesFunctions,
142 const Impl::Parameter<ParameterArgs...>&
parameter) {
143 return Impl::makeTupleOfValuesAndReferences(
145 std::make_index_sequence<std::tuple_size_v<std::remove_reference_t<
decltype(derivativesFunctions.args)>>>{});
154template <
typename TypeListOne,
typename TypeListTwo>
159 [[maybe_unused]]
const TypeListTwo& args) {
160 static_assert(!
sizeof(TypeListOne),
161 "This type should not be instantiated. check that your arguments satisfies the template below");
172template <
typename... DerivativeArgs,
typename... ParameterArgs>
173class NonLinearOperator<Impl::Functions<DerivativeArgs...>, Impl::Parameter<ParameterArgs...>>
176 using FunctionReturnValues =
178 using ParameterValues = std::tuple<ParameterArgs...>;
186 using FunctionReturnType = std::tuple_element_t<n, FunctionReturnValues>;
194 using ParameterValue = std::remove_cvref_t<std::tuple_element_t<n, ParameterValues>>;
197 std::remove_cvref_t<std::tuple_element_t<0, FunctionReturnValues>>;
198 using DerivativeType =
199 std::remove_cvref_t<std::tuple_element_t<1, FunctionReturnValues>>;
207 explicit NonLinearOperator(
const Impl::Functions<DerivativeArgs...>& derivativesFunctions,
208 const Impl::Parameter<ParameterArgs...>& parameterI)
209 : derivatives_{derivativesFunctions.args},
210 args_{parameterI.args},
211 derivativesEvaluated_(
initResults(derivativesFunctions, parameterI)) {}
219 Dune::Hybrid::forEach(
220 Dune::Hybrid::integralRange(Dune::index_constant<
sizeof...(DerivativeArgs)>()), [&](
const auto i) {
221 std::get<i>(derivativesEvaluated_) = Impl::applyAndRemoveReferenceWrapper(std::get<i>(derivatives_), args_);
232 std::get<n>(derivativesEvaluated_) = Impl::applyAndRemoveReferenceWrapper(std::get<n>(derivatives_), args_);
243 requires(
sizeof...(DerivativeArgs) > 0)
245 return nthDerivative<0>();
256 requires(
sizeof...(DerivativeArgs) > 1)
258 return nthDerivative<1>();
268 auto& secondDerivative()
269 requires(
sizeof...(DerivativeArgs) > 2)
271 return nthDerivative<2>();
281 auto& nthDerivative()
282 requires(
sizeof...(DerivativeArgs) > n)
284 if constexpr (
requires { std::get<n>(derivativesEvaluated_).get(); })
285 return std::get<n>(derivativesEvaluated_).get();
287 return std::get<n>(derivativesEvaluated_);
295 auto& lastParameter() {
return nthParameter<
sizeof...(ParameterArgs) - 1>(); }
301 auto& firstParameter()
302 requires(
sizeof...(ParameterArgs) > 0)
304 return nthParameter<0>();
311 auto& secondParameter()
312 requires(
sizeof...(ParameterArgs) > 1)
314 return nthParameter<1>();
324 requires(
sizeof...(ParameterArgs) >= n)
326 return std::get<n>(args_).get();
335 template <
int... Derivatives>
338 Impl::applyAndRemoveReferenceWrapper(parameter<ParameterArgs...>, args_));
342 using FunctionReturnValuesWrapper = std::tuple<std::conditional_t<
346 std::tuple<std::conditional_t<std::is_reference_v<DerivativeArgs>,
347 std::reference_wrapper<std::remove_reference_t<DerivativeArgs>>,
348 std::remove_reference_t<DerivativeArgs>>...>
350 std::tuple<std::conditional_t<std::is_reference_v<ParameterArgs>,
351 std::reference_wrapper<std::remove_reference_t<ParameterArgs>>,
352 std::remove_reference_t<ParameterArgs>>...>
354 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:69
Definition: simpleassemblers.hh:22
auto initResults(const Impl::Functions< DerivativeArgs... > &derivativesFunctions, const Impl::Parameter< ParameterArgs... > ¶meter)
Initializes the results for functions and parameters.
Definition: nonlinearoperator.hh:141
auto functions(Args &&... args)
Creates a Functions object.
Definition: nonlinearoperator.hh:127
auto parameter(Args &&... args)
Creates a Parameter object.
Definition: nonlinearoperator.hh:115
Represents a NonLinearOperator class for handling nonlinear operators.
Definition: nonlinearoperator.hh:156
NonLinearOperator(const TypeListOne &derivativesFunctions, const TypeListTwo &args)
Definition: nonlinearoperator.hh:158