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