pub trait TimeIntegrable:
Debug
+ Clone
+ PartialEq {
type Derivative: Debug + Clone + PartialEq;
// Required method
fn step(self, derivative: Self::Derivative, dt: Time) -> Self;
}Expand description
A trait for types that support finite time stepping via integration.
Types that implement this trait must have a well-defined time derivative and be able to advance their state over a specified time interval.
This trait is primarily intended for unit-aware physical quantities,
such as those provided by the uom crate.
It imposes no operator bounds directly. However, it is automatically
implemented for any type T that satisfies the following bounds:
T: Div<Time, Output = Derivative>: Defines the derivative asT / TimeDerivative: Mul<Time, Output = Delta>: Defines the delta asDerivative * TimeT: Add<Delta, Output = T>: Enables applying a delta to produce an updated valueTandDerivativeimplementDebug,Clone, andPartialEq
For such types, which include all uom quantities,
integration is performed using a forward Euler step:
next_value = self + derivative * dt§Example
To implement TimeIntegrable manually for a composite type,
define a corresponding derivative type and delegate the integration
logic to each field:
use twine_core::{TimeIntegrable, TimeDerivative};
use uom::si::f64::{MassDensity, ThermodynamicTemperature, Time};
#[derive(Debug, Clone, PartialEq)]
struct State<T: TimeIntegrable> {
temperature: ThermodynamicTemperature,
density: MassDensity,
other: T,
}
#[derive(Debug, Clone, PartialEq)]
struct StateTimeDerivative<T: TimeIntegrable> {
temperature: TimeDerivative<ThermodynamicTemperature>,
density: TimeDerivative<MassDensity>,
other: TimeDerivative<T>,
}
impl<T: TimeIntegrable> TimeIntegrable for State<T> {
type Derivative = StateTimeDerivative<T>;
fn step(self, derivative: Self::Derivative, dt: Time) -> Self {
Self {
temperature: self.temperature.step(derivative.temperature, dt),
density: self.density.step(derivative.density, dt),
other: self.other.step(derivative.other, dt),
}
}
}Alternatively, you can derive this implementation automatically using the
#[derive(TimeIntegrable)] macro from the [twine_macros] crate:
use twine_macros::TimeIntegrable;
use uom::si::f64::{MassDensity, ThermodynamicTemperature};
#[derive(Debug, Clone, PartialEq, TimeIntegrable)]
struct State {
temperature: ThermodynamicTemperature,
density: MassDensity,
}This generates the same StateTimeDerivative struct and TimeIntegrable
implementation as shown above.
Required Associated Types§
type Derivative: Debug + Clone + PartialEq
Required Methods§
Sourcefn step(self, derivative: Self::Derivative, dt: Time) -> Self
fn step(self, derivative: Self::Derivative, dt: Time) -> Self
Advances the value using its derivative over a time interval.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.