SpECTRE
v2024.05.11
|
Contains control system elements. More...
Namespaces | |
namespace | control_system |
Control systems and related functionality. | |
namespace | control_system::Actions |
All Actions related to the control system. | |
namespace | control_system::ControlErrors |
All control errors that will be used in control systems. | |
namespace | control_system::Systems |
All control systems. | |
namespace | control_system::size |
Classes and functions used in implementation of size control. | |
namespace | control_system::protocols |
Protocols for control systems. | |
namespace | control_system::OptionTags |
All option tags related to the control system. | |
namespace | control_system::QueueTags |
All tags that will be used in the LinkedMessageQueue's within control systems. | |
namespace | control_system::Tags |
All DataBox tags related to the control system. | |
namespace | control_system::metafunctions |
Metafunctions associated with the control systems. | |
Classes | |
struct | control_system::Actions::Initialize< Metavariables, ControlSystem > |
Initialize items related to the control system. More... | |
class | Averager< DerivOrder > |
A weighted exponential averager of \(Q\) and its derivatives implementing Appendix A in [87]. More... | |
struct | ControlComponent< Metavariables, ControlSystem > |
The singleton parallel component responsible for managing a single control system. More... | |
class | Controller< DerivOrder > |
A PND (proportional to Q and N derivatives of Q) controller that computes the control signal: More... | |
struct | control_system::measurements::Tags::NeutronStarCenter< Center > |
DataBox tag for location of neutron star center (or more accurately, center of mass of the matter in the x>0 (label A) or x<0 (label B) region, in grid coordinates). More... | |
struct | control_system::RunCallbacks< Submeasurement, ControlSystems > |
Apply the process_measurement struct of each of the ControlSystems to the result of the Submeasurement . More... | |
struct | control_system::Tags::FunctionsOfTimeInitialize |
The FunctionsOfTime initialized from a DomainCreator, initial time, and control system OptionHolders. More... | |
struct | control_system::Tags::IsActiveMap |
Tag that holds a map between control system name and whether that control system is active. Can be used in the GlobalCache. More... | |
struct | control_system::Tags::MeasurementTimescales |
The measurement timescales associated with domain::Tags::FunctionsOfTime. More... | |
struct | control_system::OptionHolder< ControlSystem > |
Holds all options for a single control system. More... | |
struct | control_system::OptionTags::ControlSystemGroup |
Options group for all control system options. More... | |
struct | control_system::OptionTags::ControlSystemInputs< ControlSystem > |
Option tag for each individual control system. The name of this option is the name of the ControlSystem struct it is templated on. This way all control systems will have a unique name. More... | |
struct | control_system::OptionTags::WriteDataToDisk |
Option tag on whether to write data to disk. More... | |
struct | control_system::OptionTags::MeasurementsPerUpdate |
Option tag that determines how many measurements will occur per control system update. More... | |
struct | control_system::OptionTags::Verbosity |
Verbosity tag for printing diagnostics about the control system algorithm. This does not control when data is written to disk. More... | |
struct | control_system::QueueTags::Center< Horizon > |
Holds the centers of each horizon from measurements as DataVectors. More... | |
struct | control_system::QueueTags::Horizon< Frame > |
Holds a full strahlkorper from measurements that represents a horizon. More... | |
struct | control_system::QueueTags::ExcisionSurface< Frame > |
Holds a full strahlkorper from measurements for the excision surface. More... | |
struct | control_system::QueueTags::LapseOnExcisionSurface |
Holds the lapse on the ExcisionSurface More... | |
struct | control_system::QueueTags::ShiftyQuantity< Frame > |
Holds a quantity that's similar to the shift, but isn't the shift, on the ExcisionSurface . More... | |
struct | control_system::QueueTags::SpatialMetricOnExcisionSurface< Frame > |
Holds the spatial metric on the ExcisionSurface More... | |
struct | control_system::QueueTags::InverseSpatialMetricOnExcisionSurface< Frame > |
Holds the inverse spatial metric on the ExcisionSurface More... | |
struct | control_system::QueueTags::SizeExcisionQuantities< Frame > |
A queue tag that holds a TaggedTuple of all quantities needed for the excision measurement of size control. More... | |
struct | control_system::QueueTags::SizeHorizonQuantities< Frame > |
A queue tag that holds a TaggedTuple of all quantities needed for the horizon measurement of size control. More... | |
struct | control_system::Tags::WriteDataToDisk |
DataBox tag for writing control system data to disk. More... | |
struct | control_system::Tags::ObserveCenters |
DataBox tag for writing the centers of the horizons to disk. More... | |
struct | control_system::Tags::Averager< ControlSystem > |
DataBox tag for the averager. More... | |
struct | control_system::Tags::TimescaleTuner< ControlSystem > |
DataBox tag for the timescale tuner. More... | |
struct | control_system::Tags::Controller< ControlSystem > |
DataBox tag for the controller. More... | |
struct | control_system::Tags::ControlError< ControlSystem > |
DataBox tag for the control error. More... | |
struct | control_system::Tags::MeasurementsPerUpdate |
Tag that determines how many measurements will occur per control system update. This will usually be stored in the global cache. More... | |
struct | control_system::Tags::CurrentNumberOfMeasurements |
DataBox tag that keeps track of which measurement we are on. More... | |
struct | control_system::Tags::Verbosity |
DataBox tag that holds the verbosity used to print info about the control system algorithm. More... | |
class | TimescaleTuner< AllowDecrease > |
Manages control system timescales. More... | |
struct | control_system::UpdateSingleFunctionOfTime |
Updates a FunctionOfTime in the global cache. Intended to be used in Parallel::mutate. More... | |
struct | control_system::UpdateMultipleFunctionsOfTime |
Updates several FunctionOfTimes in the global cache at once. Intended to be used in Parallel::mutate. More... | |
class | domain::FunctionsOfTime::FixedSpeedCubic |
Sets \(f(t)\) and derivatives using cubic rational functions, such that the first derivative approaches a constant and the second derivative approaches zero. More... | |
class | domain::FunctionsOfTime::SettleToConstant |
Given an initial function of time, transitions the map to a constant-in-time value. More... | |
class | domain::FunctionsOfTime::SettleToConstantQuaternion |
Given an initial function of time that is a unit quaternion, transitions to a constant-in-time unit quaternion. More... | |
Typedefs | |
template<typename Metavariables , typename ControlSystems > | |
using | control_system::control_components = tmpl::transform< ControlSystems, tmpl::bind< ControlComponent, tmpl::pin< Metavariables >, tmpl::_1 > > |
List of control components to be added to the component list of the metavars. | |
template<typename ControlSystems > | |
using | control_system::metafunctions::control_system_events = tmpl::flatten< tmpl::transform< metafunctions::measurements_t< ControlSystems >, detail::events_from_measurement< tmpl::pin< ControlSystems >, tmpl::_1 > > > |
The list of events needed for measurements for a list of control systems. | |
template<typename ControlSystems > | |
using | control_system::inputs = tmpl::transform< ControlSystems, tmpl::bind< OptionTags::ControlSystemInputs, tmpl::_1 > > |
Alias to get all the option holders from a list of control systems. This is useful in the option_tags alias of simple tags for getting all the options from control systems. | |
template<typename ControlSystems > | |
using | control_system::control_system_triggers = tmpl::transform< metafunctions::measurements_t< ControlSystems >, tmpl::bind< Trigger, metafunctions::control_systems_with_measurement< tmpl::pin< ControlSystems >, tmpl::_1 > > > |
The list of triggers needed for measurements for a list of control systems. | |
Functions | |
template<size_t DerivOrder, bool AllowDecrease> | |
DataVector | control_system::calculate_measurement_timescales (const ::Controller< DerivOrder > &controller, const ::TimescaleTuner< AllowDecrease > &tuner, const int measurements_per_update) |
Calculate the measurement timescale based on the damping timescale, update fraction, and DerivOrder of the control system. More... | |
double | control_system::function_of_time_expiration_time (const double time, const DataVector &old_measurement_timescales, const DataVector &new_measurement_timescales, const int measurements_per_update) |
Calculate the next expiration time for the FunctionsOfTime. More... | |
double | control_system::measurement_expiration_time (const double time, const DataVector &old_measurement_timescales, const DataVector &new_measurement_timescales, const int measurements_per_update) |
Calculate the next expiration time for the MeasurementTimescales. More... | |
template<size_t Dim, typename... OptionHolders> | |
std::unordered_map< std::string, double > | control_system::initial_expiration_times (const double initial_time, const int measurements_per_update, const std::unique_ptr<::DomainCreator< Dim > > &domain_creator, const OptionHolders &... option_holders) |
Construct the initial expiration times for functions of time that are controlled by a control system. More... | |
template<typename ControlSystem , typename Metavariables > | |
void | control_system::write_components_to_disk (const double time, Parallel::GlobalCache< Metavariables > &cache, const std::unique_ptr< domain::FunctionsOfTime::FunctionOfTime > &function_of_time, const std::array< DataVector, 2 > &q_and_dtq, const DataVector ×cales) |
Writes all components of a function of time to disk at a specific time from a control system after it updates the functions of time. More... | |
Contains control system elements.
The control system manages the time-dependent mapping between frames, such as the fixed computational frame (grid frame) and the inertial frame. The time-dependent parameters of the mapping are adjusted by a feedback control system in order to follow the dynamical evolution of objects such as horizons of black holes or surfaces of neutron stars. For example, in binary black hole simulations the map is typically a composition of maps that include translation, rotation, scaling, shape, etc. Each map under the governance of the control system has an associated time-dependent map parameter \(\lambda(t)\) that is a piecewise Nth order polynomial. At discrete times (called reset times), the control system resets the Nth time derivative of \(\lambda(t)\) to a new constant value, in order to minimize an error function \(Q(t)\) that is specific to each map. At each reset time, the Nth derivative of \(\lambda(t)\) is set to a function \(U(t)\), called the control signal, that is determined by \(Q(t)\) and its time derivatives and time integral. Note that \(\lambda(t)\), \(U(t)\), and \(Q(t)\) can be vectors.
The key components of the control system are:
\[U(t) = a_{0}\int_{t_{0}}^{t} Q(t') dt'+a_{1}Q(t)+a_{2}\frac{dQ}{dt}\]
or PND (proportional/N derivatives)\[ U(t) = \sum_{k=0}^{N} a_{k} \frac{d^kQ}{dt^k} \]
The coefficients \( a_{k} \) in the computation of \(U(t)\) are chosen at each time such that the error \(Q(t)\) will be critically damped on a timescale of \(\tau\) (the damping time), i.e. \(Q(t) \propto e^{-t/\tau}\).For additional details describing our control system approach, see [87].
DataVector control_system::calculate_measurement_timescales | ( | const ::Controller< DerivOrder > & | controller, |
const ::TimescaleTuner< AllowDecrease > & | tuner, | ||
const int | measurements_per_update | ||
) |
Calculate the measurement timescale based on the damping timescale, update fraction, and DerivOrder of the control system.
The update timescale is \(\tau_\mathrm{update} = \alpha_\mathrm{update} \tau_\mathrm{damp}\) where \(\tau_\mathrm{damp}\) is the damping timescale (from the TimescaleTuner) and \(\alpha_\mathrm{update}\) is the update fraction (from the controller). For an Nth order control system, the averager requires at least N measurements in order to perform its finite differencing to calculate the derivatives of the control error. This implies that the largest the measurement timescale can be is \(\tau_\mathrm{m} = \tau_\mathrm{update} / N\). To ensure that we have sufficient measurements, we calculate the measurement timescales as \(\tau_\mathrm{m} = \tau_\mathrm{update} / N\) where \(N\) is measurements_per_update
.
double control_system::function_of_time_expiration_time | ( | const double | time, |
const DataVector & | old_measurement_timescales, | ||
const DataVector & | new_measurement_timescales, | ||
const int | measurements_per_update | ||
) |
Calculate the next expiration time for the FunctionsOfTime.
\begin{align} T_\mathrm{expr}^\mathrm{FoT} &= t + \tau_\mathrm{m}^\mathrm{old} + N * \tau_\mathrm{m}^\mathrm{new} \\ \end{align}
where \(T_\mathrm{expr}^\mathrm{FoT}\) is the expiration time for the FunctionsOfTime, \(t\) is the update time, \(\tau_\mathrm{m}^\mathrm{old/new}\) is the measurement timescale, and \(N\) is the number of measurements per update.
The expiration is calculated this way because we update the functions of time one (old) measurement before they actually expire.
The choice of having the functions of time expire exactly one old measurement after they are updated is arbitrary. They could expire any time between the update time and one old measurement after the update. This decision was made to minimize time spent waiting for the functions of time to be valid.
Since functions of time are valid at their expiration time, we are actually able to do the next measurement if the expiration time is at that measurement. Thus we delay any potential waiting that may happen until the subsequent measurement (and by that time, most, if not all, functions of time should have been updated because an entire horizon find happened in the meantime). If the expiration time was earlier than the next measurement, we'd have to pause the Algorithm on the DG elements and wait until all the functions of time have been updated.
std::unordered_map< std::string, double > control_system::initial_expiration_times | ( | const double | initial_time, |
const int | measurements_per_update, | ||
const std::unique_ptr<::DomainCreator< Dim > > & | domain_creator, | ||
const OptionHolders &... | option_holders | ||
) |
Construct the initial expiration times for functions of time that are controlled by a control system.
The expiration times are constructed using inputs from control system OptionHolders as an unordered map from the name of the function of time being controlled to the expiration time.
The expiration time for each individual function of time is computed as \(\tau_\mathrm{exp} = \alpha_\mathrm{update} \tau_\mathrm{damp}\) where \(\alpha_\mathrm{update}\) is the update fraction supplied as input to the Controller and \(\tau_\mathrm{damp}\) is/are the damping timescales supplied from the TimescaleTuner ( \(\tau_\mathrm{damp}\) is a DataVector with as many components as the corresponding function of time, thus \(\tau_\mathrm{exp}\) will also be a DataVector of the same length).
However, this expiration time calculated above is not necessarily the expiration that is returned by this function. We group functions of time by the control_system::protocols::Measurement
that their corresponding control systems use. This is because one measurement may be used to update many functions of time. So the actual expiration time that is used for all the functions of time in this group is the minimum of the \(\tau_\mathrm{exp}\) of each function of time in the group.
These groups are calculated using control_system::system_to_combined_names
where the list of control systems comes from the passed in OptionHolder
s.
If the control system isn't active then expiration time is std::numeric_limits<double>::infinity()
, regardless of what the groups' expiration time is.
double control_system::measurement_expiration_time | ( | const double | time, |
const DataVector & | old_measurement_timescales, | ||
const DataVector & | new_measurement_timescales, | ||
const int | measurements_per_update | ||
) |
Calculate the next expiration time for the MeasurementTimescales.
\begin{align} T_\mathrm{expr}^\mathrm{m} &= T_\mathrm{expr}^\mathrm{FoT} - \frac{1}{2} \tau_\mathrm{m}^\mathrm{new} \\ \end{align}
where \(T_\mathrm{expr}^\mathrm{m}\) is the measurement expiration time, \(T_\mathrm{expr}^\mathrm{FoT}\) is the function of time expiration time as calculate from function_of_time_expiration_time()
, and \(\tau_\mathrm{m}^\mathrm{new}\) is the new measurement timescale. The reason for the factor of a half is as follows:
We update the functions of time one (old) measurement before the expiration time. Based on how dense triggers are set up, which control_system::Trigger is a dense trigger, you calculate the next trigger (measurement) time at the current measurement time. However, at the function of time expiration time we need updated damping timescales from all control systems in order to calculate when the next measurement is going to be (and in turn, the next measurement expiration time). Thus, at the measurement that occurs at the function of time expiration time, our measurement timescales can't be valid and we must wait for updated ones. To achieve this, we set the measurement expiration time before the function of time expiration time, but after the previous measurement (the update measurement). The factor of one half is just to guarantee we are more than epsilon before the function of time expiration time and more than epsilon after the update measurement.
void control_system::write_components_to_disk | ( | const double | time, |
Parallel::GlobalCache< Metavariables > & | cache, | ||
const std::unique_ptr< domain::FunctionsOfTime::FunctionOfTime > & | function_of_time, | ||
const std::array< DataVector, 2 > & | q_and_dtq, | ||
const DataVector & | timescales | ||
) |
Writes all components of a function of time to disk at a specific time from a control system after it updates the functions of time.
The columns of data written are:
Data will be stored in the reduction file. All subfiles for the control system within the H5 file will be under the group "/ControlSystems". Within this group, there will be one group for each control system. The name of each group will be the result of the name()
function from each control system. An example would look like
Then, within each system group, there will be one subfile for each component of the function of time that is being controlled. The name of this subfile is the name of the component. The name of each component will be the result of the component_name(i)
function from the control system, where i
is the index of the component. For example, if "SystemA" has 3 components with names "X", "Y", and "Z", then the subfiles would look like