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))...);
88 template <
typename... Args>
91 std::tuple<Args...> args;
99 template <
typename... Args>
102 std::tuple<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 std::tuple<DerivativeArgs...>& derivativesFunctions,
142 const std::tuple<ParameterArgs...>&
parameter) {
143 return Impl::makeTupleOfValuesAndReferences(
145 std::make_index_sequence<std::tuple_size_v<std::remove_reference_t<
decltype(derivativesFunctions)>>>{});
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...>;
180 static constexpr int numberOfFunctions =
sizeof...(DerivativeArgs);
181 static constexpr int numberOfParameters =
sizeof...(ParameterArgs);
189 using FunctionReturnType = std::tuple_element_t<n, FunctionReturnValues>;
197 using ParameterValue = std::remove_cvref_t<std::tuple_element_t<n, ParameterValues>>;
200 std::remove_cvref_t<std::tuple_element_t<0, FunctionReturnValues>>;
201 using DerivativeType =
202 std::remove_cvref_t<std::tuple_element_t<1, FunctionReturnValues>>;
210 template <
typename U =
void>
211 requires(not std::is_rvalue_reference_v<DerivativeArgs> and ...)
212 explicit
NonLinearOperator(const Impl::Functions<DerivativeArgs...>& derivativesFunctions,
213 const Impl::Parameter<ParameterArgs...>& parameterI)
214 : derivatives_{derivativesFunctions.args},
215 args_{parameterI.args},
216 derivativesEvaluated_(
initResults(derivatives_, args_)) {}
224 template <
typename Funcs>
225 explicit NonLinearOperator(
const Funcs& derivativesFunctions,
const Impl::Parameter<ParameterArgs...>& parameterI)
226 : derivatives_{derivativesFunctions.args},
227 args_{parameterI.args},
228 derivativesEvaluated_(
initResults(derivatives_, args_)) {}
236 Dune::Hybrid::forEach(
237 Dune::Hybrid::integralRange(Dune::index_constant<
sizeof...(DerivativeArgs)>()), [&](
const auto i) {
238 std::get<i>(derivativesEvaluated_) = Impl::applyAndRemoveReferenceWrapper(std::get<i>(derivatives_), args_);
249 std::get<n>(derivativesEvaluated_) = Impl::applyAndRemoveReferenceWrapper(std::get<n>(derivatives_), args_);
260 requires(
sizeof...(DerivativeArgs) > 0)
262 return nthDerivative<0>();
273 requires(
sizeof...(DerivativeArgs) > 1)
275 return nthDerivative<1>();
285 auto& secondDerivative()
286 requires(
sizeof...(DerivativeArgs) > 2)
288 return nthDerivative<2>();
298 auto& nthDerivative()
299 requires(
sizeof...(DerivativeArgs) > n)
301 if constexpr (
requires { std::get<n>(derivativesEvaluated_).get(); })
302 return std::get<n>(derivativesEvaluated_).get();
304 return std::get<n>(derivativesEvaluated_);
312 auto& lastParameter() {
return nthParameter<
sizeof...(ParameterArgs) - 1>(); }
318 auto& firstParameter()
319 requires(
sizeof...(ParameterArgs) > 0)
321 return nthParameter<0>();
328 auto& secondParameter()
329 requires(
sizeof...(ParameterArgs) > 1)
331 return nthParameter<1>();
341 requires(
sizeof...(ParameterArgs) >= n)
343 return std::get<n>(args_).get();
352 template <
int... Derivatives>
354 auto derivatives = derivatives_;
355 auto fs =
functions([&derivatives]() ->
decltype(
auto) {
return std::get<Derivatives>(derivatives); }()...);
357 Impl::Parameter<ParameterArgs...>>
358 subOp(std::move(fs), Impl::applyAndRemoveReferenceWrapper(parameter<ParameterArgs...>, args_));
364 using FunctionReturnValuesWrapper = std::tuple<std::conditional_t<
369 std::tuple<std::conditional_t<std::is_lvalue_reference_v<DerivativeArgs>,
370 std::reference_wrapper<std::remove_reference_t<DerivativeArgs>>,
371 std::remove_reference_t<DerivativeArgs>>...>
374 std::tuple<std::conditional_t<std::is_lvalue_reference_v<ParameterArgs>,
375 std::reference_wrapper<std::remove_reference_t<ParameterArgs>>,
376 std::remove_reference_t<ParameterArgs>>...>
378 FunctionReturnValuesWrapper derivativesEvaluated_{};
381template <
typename... DerivativeArgs,
typename... ParameterArgs>
382NonLinearOperator(
const Impl::Functions<DerivativeArgs&&...>& a,
const Impl::Parameter<ParameterArgs...>& b)
383 ->
NonLinearOperator<Impl::Functions<DerivativeArgs...>, Impl::Parameter<ParameterArgs...>>;
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:74
Definition: assemblermanipulatorbuildingblocks.hh:22
auto initResults(const std::tuple< DerivativeArgs... > &derivativesFunctions, const std::tuple< 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
NonLinearOperator(const Impl::Functions< DerivativeArgs &&... > &a, const Impl::Parameter< ParameterArgs... > &b) -> NonLinearOperator< Impl::Functions< DerivativeArgs... >, Impl::Parameter< ParameterArgs... > >
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