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 : } // namespace detail 80 : 81 : /// Extract the `interpolation_target_tag` aliases from all 82 : /// submeasurements for the list of control systems. This is intended 83 : /// for use in constructing the global list of interpolation target 84 : /// tags in the metavariables. 85 : template <typename ControlSystems> 86 1 : using interpolation_target_tags = tmpl::flatten<tmpl::transform< 87 : measurements_t<ControlSystems>, 88 : tmpl::lazy::transform< 89 : submeasurements<tmpl::_1>, 90 : tmpl::defer<detail::interpolation_target_tags_for_submeasurement< 91 : tmpl::_1, 92 : control_systems_with_measurement<tmpl::pin<ControlSystems>, 93 : tmpl::parent<tmpl::_1>>>>>>>; 94 : 95 : namespace detail { 96 : CREATE_GET_TYPE_ALIAS_OR_DEFAULT(component_being_mocked) 97 : 98 : template <typename Metavariables> 99 : using all_components = typename Metavariables::component_list; 100 : 101 : template <typename Metavariables> 102 : using all_not_mocked_components = 103 : tmpl::transform<all_components<Metavariables>, 104 : get_component_being_mocked_or_default<tmpl::_1, tmpl::_1>>; 105 : } // namespace detail 106 : 107 : /// Get all ControlComponent%s from the metavariables, even if they are mocked. 108 : template <typename Metavariables> 109 1 : using all_control_components = 110 : tmpl::filter<detail::all_not_mocked_components<Metavariables>, 111 : tt::is_a<ControlComponent, tmpl::_1>>; 112 : 113 : template <typename ControlSystems, typename Submeasurement> 114 0 : struct event_from_submeasurement { 115 0 : using type = typename Submeasurement::template event<ControlSystems>; 116 : }; 117 : 118 : template <typename ControlSystems, typename Submeasurement> 119 0 : using event_from_submeasurement_t = 120 : typename event_from_submeasurement<ControlSystems, Submeasurement>::type; 121 : 122 : namespace detail { 123 : template <typename AllControlSystems, typename Measurement> 124 : struct events_from_measurement { 125 : using submeasurements = submeasurements_t<Measurement>; 126 : using control_systems_with_measurement = 127 : control_systems_with_measurement_t<AllControlSystems, Measurement>; 128 : 129 : using type = tmpl::transform< 130 : submeasurements, 131 : event_from_submeasurement<tmpl::pin<control_systems_with_measurement>, 132 : tmpl::_1>>; 133 : }; 134 : template <typename AllControlSystems, typename Measurement> 135 : using events_from_measurement_t = 136 : typename events_from_measurement<AllControlSystems, Measurement>::type; 137 : } // namespace detail 138 : 139 : /// \ingroup ControlSystemGroup 140 : /// The list of events needed for measurements for a list of control 141 : /// systems. 142 : template <typename ControlSystems> 143 1 : using control_system_events = tmpl::flatten<tmpl::transform< 144 : metafunctions::measurements_t<ControlSystems>, 145 : detail::events_from_measurement<tmpl::pin<ControlSystems>, tmpl::_1>>>; 146 : } // namespace metafunctions 147 : } // namespace control_system