pub fn rkmk_dae_step<Field, Tab, Z, T>(
rate: &mut impl FnMut(Quantity<T>, &Field::Point, &Z) -> Result<Derivative<Field::Increment, T>, String>,
solve: &mut impl FnMut(Quantity<T>, &Field::Point, &Z) -> Result<Z, String>,
point: &Field::Point,
z: &Z,
t: Quantity<T>,
dt: Quantity<T>,
scratch: &mut Vec<Field::Increment>,
first_rate: Option<&Derivative<Field::Increment, T>>,
) -> Result<(Field::Point, Z, Option<Derivative<Field::Increment, T>>), IntegrationError>where
Field: Integrable,
Tab: ButcherTableau,
Field::Point: Clone,
Field::Increment: Clone + Differentiable<T>,
Z: Clone,
T: Copy,
Quantity<T>: Mul<Scalar, Output = Quantity<T>>,
for<'a> &'a Derivative<Field::Increment, T>: Mul<Quantity<T>, Output = Field::Increment>,Expand description
One RKMK step of a semi-explicit DAE: the differential field advances on its manifold while the algebraic unknown is re-solved from its constraint at every stage abscissa.
rkmk_step freezes the drive across the whole window, which caps the
coupling at first order however the two legs are ordered. Here solve
supplies z at each stage time t + cᵢ Δt from the stage point, so the
drive is resolved within the window — the half-explicit RK treatment of an
index-1 DAE, but with the state leg kept on its group.
solve is seeded with the previous stage’s z and must return a z
satisfying the constraint at the stage it is given; the returned z is the
one consistent with the step’s own endpoint.
FSAL: first_rate seeds stage 0 with a rate carried from the previous
step, skipping both that rate evaluation and its constraint solve (z
stays the z passed in, which is already consistent with (t, point));
when Tab::FSAL, the raw rate at the final stage is returned for the next
step to seed with.