Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <optional>
7 :
8 : #include "DataStructures/DataBox/DataBox.hpp"
9 : #include "Evolution/Imex/Protocols/ImexSystem.hpp"
10 : #include "Evolution/Imex/SolveImplicitSector.hpp"
11 : #include "Parallel/AlgorithmExecution.hpp"
12 : #include "Time/TimeStepId.hpp"
13 : #include "Utilities/CleanupRoutine.hpp"
14 : #include "Utilities/Gsl.hpp"
15 : #include "Utilities/ProtocolHelpers.hpp"
16 : #include "Utilities/TMPL.hpp"
17 :
18 : /// \cond
19 : namespace Parallel {
20 : template <typename Metavariables>
21 : class GlobalCache;
22 : } // namespace Parallel
23 : namespace Tags {
24 : template <typename Tag>
25 : struct Next;
26 : struct Time;
27 : struct TimeStepId;
28 : } // namespace Tags
29 : namespace db {
30 : template <typename TagsList>
31 : class DataBox;
32 : } // namespace db
33 : namespace tuples {
34 : template <class... Tags>
35 : class TaggedTuple;
36 : } // namespace tuples
37 : /// \endcond
38 :
39 1 : namespace imex::Actions {
40 : /// \ingroup ActionsGroup
41 : /// \brief Perform implicit variable updates for one substep
42 : ///
43 : /// Uses:
44 : /// - DataBox:
45 : /// - Tags::Next<Tags::TimeStepId>
46 : /// - Tags::Time
47 : /// - Tags::TimeStep
48 : /// - Tags::TimeStepper<ImexTimeStepper>
49 : /// - imex::Tags::Mode
50 : /// - imex::Tags::SolveTolerance
51 : /// - as required by system implicit sectors
52 : ///
53 : /// DataBox changes:
54 : /// - variables_tag
55 : /// - imex::Tags::ImplicitHistory<sector> for each sector
56 : template <typename System>
57 1 : struct DoImplicitStep {
58 : template <typename DbTags, typename... InboxTags, typename Metavariables,
59 : typename ArrayIndex, typename ActionList,
60 : typename ParallelComponent>
61 0 : static Parallel::iterable_action_return_t apply(
62 : db::DataBox<DbTags>& box, tuples::TaggedTuple<InboxTags...>& /*inboxes*/,
63 : const Parallel::GlobalCache<Metavariables>& /*cache*/,
64 : const ArrayIndex& /*array_index*/, ActionList /*meta*/,
65 : const ParallelComponent* const /*meta*/) {
66 : static_assert(tt::assert_conforms_to_v<System, protocols::ImexSystem>);
67 :
68 : const double original_time = db::get<::Tags::Time>(box);
69 : const CleanupRoutine reset_time = [&]() {
70 : db::mutate<::Tags::Time>(
71 : [&](const gsl::not_null<double*> time) { *time = original_time; },
72 : make_not_null(&box));
73 : };
74 : db::mutate<::Tags::Time>(
75 : [](const gsl::not_null<double*> time,
76 : const TimeStepId& next_time_step_id) {
77 : *time = next_time_step_id.substep_time();
78 : },
79 : make_not_null(&box), db::get<::Tags::Next<::Tags::TimeStepId>>(box));
80 :
81 : tmpl::for_each<typename System::implicit_sectors>([&](auto sector_v) {
82 : using sector = tmpl::type_from<decltype(sector_v)>;
83 : db::mutate_apply<
84 : SolveImplicitSector<typename System::variables_tag, sector>>(
85 : make_not_null(&box));
86 : });
87 : return {Parallel::AlgorithmExecution::Continue, std::nullopt};
88 : }
89 : };
90 : } // namespace imex::Actions
|