fn step_thermal_model(&mut self, dt: Seconds, num_operations: f64) {
            // Define the derivative closure for `rkf45_adaptive`.
            let p = &self.thermal_model_params;
            let dydt = |_t: f64, y: &[f64]| -> Vec<f64> {
                // Aliases for convenience. `0` refers to the CPU and `1` refers to the heat sink,
                // corresponding to their indices in the `temperatures` array passed to
                // rkf45_adaptive.
                let a01 = p.cpu_to_heat_sink_thermal_rate;
                let a1env = p.heat_sink_to_env_thermal_rate;
                let c0 = p.cpu_thermal_capacity;
                let c1 = p.heat_sink_thermal_capacity;

                let power = self.get_cpu_power(self.p_state_index, num_operations / dt);
                vec![
                    (a01 * (y[1] - y[0]) + power.0) / c0,
                    (a01 * (y[0] - y[1]) + a1env * (self.environment_temperature.0 - y[1])) / c1,
                ]
            };

            // Configure `rkf45_adaptive`.
            //
            // The choice for `dt_initial` is currently naive. Given the need, we could try to
            // choose it more intelligently to avoide some discarded time steps in `rkf45_adaptive.`
            //
            // `error_control` is chosen to keep errors near f32 machine epsilon.
            let solver_options = rkf45::AdaptiveOdeSolverOptions {
                t_initial: self.time.0,
                t_final: (self.time + dt).0,
                dt_initial: dt.0,
                error_control: rkf45::ErrorControlOptions::simple(1e-8),
            };

            // Run `rkf45_adaptive`, and update the simulated temperatures.
            let mut temperatures = [self.cpu_temperature.0, self.heat_sink_temperature.0];
            rkf45::rkf45_adaptive(&mut temperatures, &dydt, &solver_options).unwrap();
            self.cpu_temperature = Celsius(temperatures[0]);
            self.heat_sink_temperature = Celsius(temperatures[1]);
        }
/// Steps the thermal model ahead in time by `dt`.
Steps the thermal model ahead in time by `dt`.
Steps the thermal model ahead in time by ` dt ` .
fn step_thermal_model(&mut self, dt: Seconds, num_operations: f64) {
            // Define the derivative closure for `rkf45_adaptive`.
            let p = &self.thermal_model_params;
            let dydt = |_t: f64, y: &[f64]| -> Vec<f64> {
                // Aliases for convenience. `0` refers to the CPU and `1` refers to the heat sink,
                // corresponding to their indices in the `temperatures` array passed to
                // rkf45_adaptive.
                let a01 = p.cpu_to_heat_sink_thermal_rate;
                let a1env = p.heat_sink_to_env_thermal_rate;
                let c0 = p.cpu_thermal_capacity;
                let c1 = p.heat_sink_thermal_capacity;
                let power = self.get_cpu_power(self.p_state_index, num_operations / dt);
                vec![
                    (a01 * (y[1] - y[0]) + power.0) / c0,
                    (a01 * (y[0] - y[1]) + a1env * (self.environment_temperature.0 - y[1])) / c1,
                ]
            };
            // Configure `rkf45_adaptive`.
            //
            // The choice for `dt_initial` is currently naive. Given the need, we could try to
            // choose it more intelligently to avoide some discarded time steps in `rkf45_adaptive.`
            //
            // `error_control` is chosen to keep errors near f32 machine epsilon.
            let solver_options = rkf45::AdaptiveOdeSolverOptions {
                t_initial: self.time.0,
                t_final: (self.time + dt).0,
                dt_initial: dt.0,
                error_control: rkf45::ErrorControlOptions::simple(1e-8),
            };
            // Run `rkf45_adaptive`, and update the simulated temperatures.
            let mut temperatures = [self.cpu_temperature.0, self.heat_sink_temperature.0];
            rkf45::rkf45_adaptive(&mut temperatures, &dydt, &solver_options).unwrap();
            self.cpu_temperature = Celsius(temperatures[0]);
            self.heat_sink_temperature = Celsius(temperatures[1]);
        }
fn step_thermal_model ( & mut self , dt : Seconds , num_operations : f64 ) { // Define the derivative closure for `rkf45_adaptive`. let p = & self . thermal_model_params ; let dydt = | _t : f64 , y : & [ f64 ] | -> Vec < f64 > { // Aliases for convenience. `0` refers to the CPU and `1` refers to the heat sink, // corresponding to their indices in the `temperatures` array passed to // rkf45_adaptive. let a01 = p . cpu_to_heat_sink_thermal_rate ; let a1env = p . heat_sink_to_env_thermal_rate ; let c0 = p . cpu_thermal_capacity ; let c1 = p . heat_sink_thermal_capacity ; let power = self . get_cpu_power ( self . p_state_index , num_operations / dt ) ; vec ! [ ( a01 ( y [ 1 ] y [ 0 ] ) power 0 ) c0 ( a01 ( y [ 0 ] y [ 1 ] ) a1env ( self environment_temperature 0 y [ 1 ] ) ) c1 ] } ; // Configure `rkf45_adaptive`. // // The choice for `dt_initial` is currently naive. Given the need, we could try to // choose it more intelligently to avoide some discarded time steps in `rkf45_adaptive.` // // `error_control` is chosen to keep errors near f32 machine epsilon. let solver_options = rkf45 :: AdaptiveOdeSolverOptions { t_initial : self . time . 0 , t_final : ( self . time + dt ) . 0 , dt_initial : dt . 0 , error_control : rkf45 :: ErrorControlOptions :: simple ( 1e-8 ) , } ; // Run `rkf45_adaptive`, and update the simulated temperatures. let mut temperatures = [ self . cpu_temperature . 0 , self . heat_sink_temperature . 0 ] ; rkf45 :: rkf45_adaptive ( & mut temperatures , & dydt , & solver_options ) . unwrap ( ) ; self . cpu_temperature = Celsius ( temperatures [ 0 ] ) ; self . heat_sink_temperature = Celsius ( temperatures [ 1 ] ) ; }
Steps the thermal model ahead in time by `dt`.
Steps the thermal model ahead in time by ` dt ` .
&mut self
dt
Seconds
num_operations
f64