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