Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <memory>
7 : #include <string>
8 : #include <type_traits>
9 : #include <unordered_map>
10 :
11 : #include "ControlSystem/ExpirationTimes.hpp"
12 : #include "ControlSystem/Tags/IsActiveMap.hpp"
13 : #include "ControlSystem/Tags/OptionTags.hpp"
14 : #include "ControlSystem/Tags/SystemTags.hpp"
15 : #include "DataStructures/DataBox/Tag.hpp"
16 : #include "Domain/Creators/OptionTags.hpp"
17 : #include "Domain/Creators/Tags/FunctionsOfTime.hpp"
18 : #include "Domain/FunctionsOfTime/FunctionOfTime.hpp"
19 : #include "Domain/FunctionsOfTime/Tags.hpp"
20 : #include "Options/Auto.hpp"
21 : #include "Time/OptionTags/InitialTime.hpp"
22 : #include "Time/OptionTags/InitialTimeStep.hpp"
23 : #include "Utilities/TMPL.hpp"
24 : #include "Utilities/TypeTraits/IsA.hpp"
25 :
26 : /// \cond
27 : template <class Metavariables, typename ControlSystem>
28 : struct ControlComponent;
29 : /// \endcond
30 :
31 : namespace control_system::Tags {
32 : namespace detail {
33 : // Check that all control systems are actually controlling a function of
34 : // time, and that the expiration times have been set appropriately. If there
35 : // exists a control system that isn't controlling a function of time, or the
36 : // expiration times were set improperly, this is an error and we shouldn't
37 : // continue.
38 : void check_expiration_time_consistency(
39 : const std::unordered_map<std::string, double>& initial_expiration_times,
40 : const std::unordered_map<std::string, bool>& is_active_map,
41 : const std::unordered_map<
42 : std::string, std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>>&
43 : functions_of_time);
44 : } // namespace detail
45 :
46 : /// \ingroup ControlSystemGroup
47 : /// The FunctionsOfTime initialized from a DomainCreator, initial time, and
48 : /// control system OptionHolders.
49 1 : struct FunctionsOfTimeInitialize : domain::Tags::FunctionsOfTime {
50 0 : using base = domain::Tags::FunctionsOfTime;
51 :
52 0 : static constexpr bool pass_metavariables = true;
53 :
54 0 : static std::string name() { return "FunctionsOfTime"; }
55 :
56 : template <typename Metavariables>
57 0 : using option_holders = control_system::inputs<
58 : tmpl::transform<tmpl::filter<typename Metavariables::component_list,
59 : tt::is_a<ControlComponent, tmpl::_1>>,
60 : tmpl::bind<tmpl::back, tmpl::_1>>>;
61 :
62 : template <typename Metavariables>
63 0 : static constexpr bool metavars_has_control_systems =
64 : tmpl::size<option_holders<Metavariables>>::value > 0;
65 :
66 : template <typename Metavariables>
67 0 : using option_tags = tmpl::push_front<
68 : tmpl::conditional_t<
69 : metavars_has_control_systems<Metavariables>,
70 : tmpl::flatten<tmpl::list<
71 : control_system::OptionTags::MeasurementsPerUpdate,
72 : control_system::OptionTags::DelayUpdate,
73 : ::OptionTags::InitialTime, option_holders<Metavariables>>>,
74 : tmpl::list<>>,
75 : domain::OptionTags::DomainCreator<Metavariables::volume_dim>>;
76 :
77 : /// @{
78 : /// This version of create_from_options is used if the metavariables did
79 : /// define control systems
80 : template <typename Metavariables, typename... OptionHolders>
81 1 : static type create_from_options(
82 : const std::unique_ptr<::DomainCreator<Metavariables::volume_dim>>&
83 : domain_creator,
84 : const int measurements_per_update, const bool delay_update,
85 : const double initial_time,
86 : const Options::Auto<OptionHolders,
87 : Options::AutoLabel::None>&... option_holders) {
88 : return create_from_options<Metavariables>(
89 : domain_creator, measurements_per_update, delay_update, initial_time,
90 : static_cast<const std::optional<OptionHolders>&>(option_holders)...);
91 : }
92 :
93 : template <typename Metavariables, typename... OptionHolders>
94 1 : static type create_from_options(
95 : const std::unique_ptr<::DomainCreator<Metavariables::volume_dim>>&
96 : domain_creator,
97 : const int measurements_per_update, const bool delay_update,
98 : const double initial_time,
99 : const std::optional<OptionHolders>&... option_holders) {
100 : const auto initial_expiration_times =
101 : control_system::initial_expiration_times(
102 : initial_time, measurements_per_update, delay_update, domain_creator,
103 : option_holders...);
104 :
105 : // We need to check the expiration times so we can ensure a proper domain
106 : // creator was chosen from options.
107 : auto functions_of_time =
108 : domain_creator->functions_of_time(initial_expiration_times);
109 :
110 : const auto is_active_map = detail::create_is_active_map(option_holders...);
111 :
112 : detail::check_expiration_time_consistency(initial_expiration_times,
113 : is_active_map, functions_of_time);
114 :
115 : return functions_of_time;
116 : }
117 : /// @}
118 :
119 : /// This version of create_from_options is used if the metavariables did not
120 : /// define control systems
121 : template <typename Metavariables>
122 1 : static type create_from_options(
123 : const std::unique_ptr<::DomainCreator<Metavariables::volume_dim>>&
124 : domain_creator) {
125 : return domain_creator->functions_of_time();
126 : }
127 : };
128 : } // namespace control_system::Tags
|