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