Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <type_traits>
7 :
8 : #include "Utilities/TMPL.hpp"
9 : #include "Utilities/TypeTraits/CreateGetTypeAliasOrDefault.hpp"
10 : #include "Utilities/TypeTraits/IsA.hpp"
11 :
12 : /// \cond
13 : template <class Metavariables, typename ControlSystem>
14 : struct ControlComponent;
15 : /// \endcond
16 :
17 : namespace control_system {
18 : /// \ingroup ControlSystemGroup
19 : /// Metafunctions associated with the control systems
20 1 : namespace metafunctions {
21 : /// Extract the `measurement` alias from a control system struct.
22 : template <typename ControlSystem>
23 1 : struct measurement {
24 0 : using type = typename ControlSystem::measurement;
25 : };
26 :
27 : /// Given a list of control systems, obtain a list of distinct control
28 : /// system measurement structs used by them.
29 : /// @{
30 : template <typename ControlSystems>
31 1 : struct measurements {
32 0 : using type = tmpl::remove_duplicates<
33 : tmpl::transform<ControlSystems, measurement<tmpl::_1>>>;
34 : };
35 :
36 : template <typename ControlSystems>
37 0 : using measurements_t = typename measurements<ControlSystems>::type;
38 : /// @}
39 :
40 : /// Given a list of control systems, extract those using a given
41 : /// measurement.
42 : /// @{
43 : template <typename ControlSystems, typename Measurement>
44 1 : struct control_systems_with_measurement
45 : : tmpl::lazy::filter<ControlSystems, std::is_same<measurement<tmpl::_1>,
46 : tmpl::pin<Measurement>>> {
47 : };
48 :
49 : template <typename ControlSystems, typename Measurement>
50 0 : using control_systems_with_measurement_t =
51 : typename control_systems_with_measurement<ControlSystems,
52 : Measurement>::type;
53 : /// @}
54 :
55 : /// Given a measurement, obtain a list of its submeasurements (i.e.,
56 : /// `Measurement::submeasurements`).
57 : /// @{
58 : template <typename Measurement>
59 1 : struct submeasurements {
60 0 : using type = typename Measurement::submeasurements;
61 : };
62 :
63 : template <typename Measurement>
64 0 : using submeasurements_t = typename submeasurements<Measurement>::type;
65 : /// @}
66 :
67 : namespace detail {
68 : template <typename Submeasurement, typename ControlSystems>
69 : struct interpolation_target_tags_for_submeasurement {
70 : private:
71 : using declared_type =
72 : typename Submeasurement::template interpolation_target_tag<
73 : ControlSystems>;
74 :
75 : public:
76 : using type = tmpl::conditional_t<std::is_same_v<declared_type, void>,
77 : tmpl::list<>, tmpl::list<declared_type>>;
78 : };
79 :
80 : template <typename Submeasurement, typename ControlSystems>
81 : struct horizon_metavars_for_submeasurement {
82 : private:
83 : using declared_type =
84 : typename Submeasurement::template horizon_metavars<ControlSystems>;
85 :
86 : public:
87 : using type = tmpl::conditional_t<std::is_same_v<declared_type, void>,
88 : tmpl::list<>, tmpl::list<declared_type>>;
89 : };
90 : } // namespace detail
91 :
92 : /// Extract the `interpolation_target_tag` aliases from all
93 : /// submeasurements for the list of control systems. This is intended
94 : /// for use in constructing the global list of interpolation target
95 : /// tags in the metavariables.
96 : template <typename ControlSystems>
97 1 : using interpolation_target_tags = tmpl::flatten<tmpl::transform<
98 : measurements_t<ControlSystems>,
99 : tmpl::lazy::transform<
100 : submeasurements<tmpl::_1>,
101 : tmpl::defer<detail::interpolation_target_tags_for_submeasurement<
102 : tmpl::_1,
103 : control_systems_with_measurement<tmpl::pin<ControlSystems>,
104 : tmpl::parent<tmpl::_1>>>>>>>;
105 :
106 : template <typename ControlSystems>
107 0 : using horizon_metavars = tmpl::flatten<tmpl::transform<
108 : measurements_t<ControlSystems>,
109 : tmpl::lazy::transform<
110 : submeasurements<tmpl::_1>,
111 : tmpl::defer<detail::horizon_metavars_for_submeasurement<
112 : tmpl::_1,
113 : control_systems_with_measurement<tmpl::pin<ControlSystems>,
114 : tmpl::parent<tmpl::_1>>>>>>>;
115 :
116 : namespace detail {
117 : CREATE_GET_TYPE_ALIAS_OR_DEFAULT(component_being_mocked)
118 :
119 : template <typename Metavariables>
120 : using all_components = typename Metavariables::component_list;
121 :
122 : template <typename Metavariables>
123 : using all_not_mocked_components =
124 : tmpl::transform<all_components<Metavariables>,
125 : get_component_being_mocked_or_default<tmpl::_1, tmpl::_1>>;
126 : } // namespace detail
127 :
128 : /// Get all ControlComponent%s from the metavariables, even if they are mocked.
129 : template <typename Metavariables>
130 1 : using all_control_components =
131 : tmpl::filter<detail::all_not_mocked_components<Metavariables>,
132 : tt::is_a<ControlComponent, tmpl::_1>>;
133 :
134 : template <typename ControlSystems, typename Submeasurement>
135 0 : struct event_from_submeasurement {
136 0 : using type = typename Submeasurement::template event<ControlSystems>;
137 : };
138 :
139 : template <typename ControlSystems, typename Submeasurement>
140 0 : using event_from_submeasurement_t =
141 : typename event_from_submeasurement<ControlSystems, Submeasurement>::type;
142 :
143 : namespace detail {
144 : template <typename AllControlSystems, typename Measurement>
145 : struct events_from_measurement {
146 : using submeasurements = submeasurements_t<Measurement>;
147 : using control_systems_with_measurement =
148 : control_systems_with_measurement_t<AllControlSystems, Measurement>;
149 :
150 : using type = tmpl::transform<
151 : submeasurements,
152 : event_from_submeasurement<tmpl::pin<control_systems_with_measurement>,
153 : tmpl::_1>>;
154 : };
155 : template <typename AllControlSystems, typename Measurement>
156 : using events_from_measurement_t =
157 : typename events_from_measurement<AllControlSystems, Measurement>::type;
158 : } // namespace detail
159 :
160 : /// \ingroup ControlSystemGroup
161 : /// The list of events needed for measurements for a list of control
162 : /// systems.
163 : template <typename ControlSystems>
164 1 : using control_system_events = tmpl::flatten<tmpl::transform<
165 : metafunctions::measurements_t<ControlSystems>,
166 : detail::events_from_measurement<tmpl::pin<ControlSystems>, tmpl::_1>>>;
167 : } // namespace metafunctions
168 : } // namespace control_system
|