Skip to main content

consistent_reverse

Function consistent_reverse 

Source
pub fn consistent_reverse(
    forward: ForwardRate,
    delta_h: f64,
    kc: f64,
    temperature_k: f64,
) -> ForwardRate
Expand description

Derive the reverse Arrhenius pair that makes a reversible rate law thermodynamically consistent at the reactor temperature.

§Why this function has to exist

dwsim-libs’ Reaction::net_rate evaluates rate = k_f(T)·ΠCᵈ − k_r(T)·ΠCʳ with k_f and k_r as two independent Arrhenius pairs. It never consults k_eq. So nothing in that API stops a caller specifying a reaction whose kinetics settle at a composition its own equilibrium constant says is wrong — the rate law and the thermodynamics simply disagree, silently, and the reactor converges to the kinetic answer.

Mass-action orders make the equilibrium condition k_f/k_r = Kc, so the reverse constant is pinned once k_f and the thermodynamics are known:

  k_r(T) = k_f(T) / Kc(T)

§Why it is anchored at one temperature rather than derived once

The tempting move is to match the Arrhenius forms symbolically — A_r = A_f·exp(−ΔS°/R), E_r = E_f − ΔH° — which makes k_f/k_r equal Kp at every temperature. That is exactly right, and exactly wrong here: the rate law needs Kc, and Kc = Kp·(P°/RT)^Δn carries a factor of T^{−Δn} that no Arrhenius pair can reproduce. For reforming (Δn = +2) that factor changes by 2.6x across 800–1300 K, so a single pair cannot be consistent over a range.

Since this model is isothermal — one temperature per solve — the honest resolution is to make consistency exact at that temperature. The activation energy still takes its physically meaningful value E_r = E_f − ΔH° (so an endothermic reaction gets the lower reverse barrier, as it should), and A_r is then whatever makes the ratio come out right:

  A_r = (k_f(T) / Kc(T)) · exp(E_r / (R T))

Verified to 1e-12 relative over 700–1400 K by reverse_rate_is_thermodynamically_consistent, which rebuilds the pair at each temperature exactly as a solve does.

A sweep therefore rebuilds its reactions per point, which smr_reactions takes the temperature for. Reusing one reactor across a temperature sweep would silently break consistency everywhere but the anchor point.