Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <tuple>
7 : #include <type_traits>
8 :
9 : #include "DataStructures/Tensor/TypeAliases.hpp"
10 : #include "Evolution/Imex/Mode.hpp"
11 : #include "Evolution/Imex/Protocols/ImplicitSector.hpp"
12 : #include "Utilities/Gsl.hpp"
13 : #include "Utilities/ProtocolHelpers.hpp"
14 : #include "Utilities/TMPL.hpp"
15 :
16 : /// \cond
17 : class DataVector;
18 : class ImexTimeStepper;
19 : class TimeDelta;
20 : template <typename TagsList>
21 : class Variables;
22 : namespace Tags {
23 : struct TimeStep;
24 : template <typename StepperInterface>
25 : struct TimeStepper;
26 : } // namespace Tags
27 : namespace TimeSteppers {
28 : template <typename Vars>
29 : class History;
30 : } // namespace TimeSteppers
31 : namespace imex::Tags {
32 : template <typename ImplicitSector>
33 : struct ImplicitHistory;
34 : struct Mode;
35 : template <typename Sector>
36 : struct SolveFailures;
37 : struct SolveTolerance;
38 : } // namespace imex::Tags
39 : /// \endcond
40 :
41 : namespace imex {
42 : namespace solve_implicit_sector_detail {
43 : template <typename Tags>
44 : using ForwardTuple = tmpl::wrap<
45 : tmpl::transform<Tags, std::add_lvalue_reference<std::add_const<
46 : tmpl::bind<tmpl::type_from, tmpl::_1>>>>,
47 : std::tuple>;
48 : } // namespace solve_implicit_sector_detail
49 :
50 : /// Perform the implicit solve for one implicit sector.
51 : ///
52 : /// This will update the tensors in the implicit sector and clean up
53 : /// the corresponding time stepper history. A new history entry is
54 : /// not added, because that should be done with the same values of the
55 : /// variables used for the explicit portion of the time derivative,
56 : /// which may still undergo variable-fixing-like corrections.
57 : ///
58 : /// \warning
59 : /// This will use the value of `::Tags::Time` from the DataBox. Most
60 : /// of the time, the value appropriate for evaluating the explicit RHS
61 : /// is stored there, so it will likely need to be set to the
62 : /// appropriate value for the implicit RHS for the duration of this
63 : /// mutation.
64 : template <typename SystemVariablesTag, typename ImplicitSector>
65 1 : struct SolveImplicitSector {
66 : static_assert(
67 : tt::assert_conforms_to_v<ImplicitSector, protocols::ImplicitSector>);
68 :
69 : public:
70 0 : using SystemVariables = typename SystemVariablesTag::type;
71 0 : using SectorVariables = Variables<typename ImplicitSector::tensors>;
72 :
73 : private:
74 : template <typename Attempt>
75 0 : struct get_tags_from_evolution {
76 0 : using type = typename Attempt::tags_from_evolution;
77 : };
78 :
79 0 : using tags_for_each_attempt =
80 : tmpl::transform<typename ImplicitSector::solve_attempts,
81 : get_tags_from_evolution<tmpl::_1>>;
82 : // List of tags used for the initial guess followed by lists of tags
83 : // used for each solve attempt.
84 0 : using evolution_data_tags =
85 : tmpl::push_front<tags_for_each_attempt,
86 : typename ImplicitSector::initial_guess::argument_tags>;
87 :
88 0 : using EvolutionDataTuple = solve_implicit_sector_detail::ForwardTuple<
89 : tmpl::join<evolution_data_tags>>;
90 :
91 0 : static void apply_impl(
92 : gsl::not_null<SystemVariables*> system_variables,
93 : gsl::not_null<Scalar<DataVector>*> solve_failures,
94 : const ImexTimeStepper& time_stepper, const TimeDelta& time_step,
95 : const TimeSteppers::History<SectorVariables>& implicit_history,
96 : Mode implicit_solve_mode, double implicit_solve_tolerance,
97 : const EvolutionDataTuple& joined_evolution_data);
98 :
99 : public:
100 0 : using return_tags =
101 : tmpl::list<SystemVariablesTag, Tags::SolveFailures<ImplicitSector>>;
102 0 : using argument_tags = tmpl::append<
103 : tmpl::list<::Tags::TimeStepper<ImexTimeStepper>, ::Tags::TimeStep,
104 : imex::Tags::ImplicitHistory<ImplicitSector>, Tags::Mode,
105 : Tags::SolveTolerance>,
106 : tmpl::join<evolution_data_tags>>;
107 :
108 : template <typename... ForwardArgs>
109 0 : static void apply(
110 : const gsl::not_null<SystemVariables*> system_variables,
111 : const gsl::not_null<Scalar<DataVector>*> solve_failures,
112 : const ImexTimeStepper& time_stepper, const TimeDelta& time_step,
113 : const TimeSteppers::History<SectorVariables>& implicit_history,
114 : const Mode implicit_solve_mode, const double implicit_solve_tolerance,
115 : const ForwardArgs&... forward_args) {
116 : apply_impl(system_variables, solve_failures, time_stepper, time_step,
117 : implicit_history, implicit_solve_mode, implicit_solve_tolerance,
118 : std::forward_as_tuple(forward_args...));
119 : }
120 : };
121 : } // namespace imex
|