Files
2026-02-16 21:52:26 +08:00

111 lines
3.9 KiB
Markdown

SIM_API_v1:
functions:
params_to_constitutive:
description: "Computes state-dependent battery parameters with guards."
inputs:
x: "[z, v_p, T_b, S, w]"
params: "MODEL_SPEC.parameters"
outputs:
V_oc: "Open-circuit voltage [V]"
R0: "Internal resistance [Ohm]"
Q_eff: "Effective capacity [Ah]"
logic:
- "z_eff = max(z, params.z_min)"
- "V_oc = params.E0 - params.K * (1/z_eff - 1) + params.A * exp(-params.B * (1 - z))"
- "R0 = params.R_ref * exp((params.E_a / params.R_g) * (1/T_b - 1/params.T_ref)) * (1 + params.eta_R * (1 - S))"
- "Q_eff = max(params.Q_nom * S * (1 - params.alpha_Q * (params.T_ref - T_b)), params.Q_eff_floor)"
power_mapping:
description: "Maps user inputs and radio state to total power demand."
inputs:
u: "[L, C, N, Ψ, T_a]"
x: "[z, v_p, T_b, S, w]"
params: "MODEL_SPEC.parameters"
outputs:
P_tot: "Total power [W]"
logic:
- "P_scr = params.P_scr0 + params.k_L * L^params.gamma"
- "P_cpu = params.P_cpu0 + params.k_C * C^params.eta"
- "P_net = params.P_net0 + params.k_N * N / (Ψ + params.epsilon)^params.kappa + params.k_tail * w"
- "P_tot = params.P_bg + P_scr + P_cpu + P_net"
current_cpl:
description: "Solves the quadratic CPL equation for current."
inputs:
V_oc: "[V]"
v_p: "[V]"
R0: "[Ohm]"
P_tot: "[W]"
outputs:
Delta: "Discriminant [V^2]"
I: "Current [A]"
logic:
- "Delta = (V_oc - v_p)^2 - 4 * R0 * P_tot"
- "I = (Delta >= 0) ? (V_oc - v_p - sqrt(Delta)) / (2 * R0) : NaN"
rhs:
description: "Computes the derivative vector and algebraic variables."
inputs:
t: "Time [s]"
x: "[z, v_p, T_b, S, w]"
u: "[L, C, N, Ψ, T_a]"
params: "MODEL_SPEC.parameters"
outputs:
dx_dt: "[dz/dt, dv_p/dt, dT_b/dt, dS/dt, dw/dt]"
algebraics: "{Delta, I, V_term, V_oc, R0, Q_eff, P_tot}"
logic:
- "V_oc, R0, Q_eff = params_to_constitutive(x, params)"
- "P_tot = power_mapping(u, x, params)"
- "Delta, I = current_cpl(V_oc, v_p, R0, P_tot)"
- "V_term = V_oc - v_p - I * R0"
- "dz_dt = -I / (3600 * Q_eff)"
- "dvp_dt = I/params.C1 - v_p / (params.R1 * params.C1)"
- "dTb_dt = (I^2 * R0 + I * v_p - params.hA * (T_b - T_a)) / params.C_th"
- "dS_dt = 0 (Single discharge assumption, or use MODEL_SPEC Option A)"
- "sigma_N = min(1, N)"
- "tau_N = (sigma_N >= w) ? params.tau_up : params.tau_down"
- "dw_dt = (sigma_N - w) / tau_N"
- "return [dz_dt, dvp_dt, dTb_dt, dS_dt, dw_dt], {Delta, I, V_term, V_oc, R0, Q_eff, P_tot}"
rk4_step:
logic:
- "u_n = scenario.u(t_n)"
- "k1, alg_n = rhs(t_n, x_n, u_n, params)"
- "k2, _ = rhs(t_n + dt/2, x_n + dt*k1/2, scenario.u(t_n + dt/2), params)"
- "k3, _ = rhs(t_n + dt/2, x_n + dt*k2/2, scenario.u(t_n + dt/2), params)"
- "k4, _ = rhs(t_n + dt, x_n + dt*k3, scenario.u(t_n + dt), params)"
- "x_next_raw = x_n + dt*(k1 + 2*k2 + 2*k3 + k4)/6"
- "x_next = [clamp(x_next_raw[0],0,1), x_next_raw[1], x_next_raw[2], clamp(x_next_raw[3],0,1), clamp(x_next_raw[4],0,1)]"
- "Store alg_n and x_n at t_n"
OutputSchema:
trajectory_columns:
- t
- z
- v_p
- T_b
- S
- w
- V_oc
- R0
- Q_eff
- P_tot
- Delta
- I
- V_term
metadata:
- dt
- t_max
- termination_reason
- t_star
- TTE_seconds
ValidationPlan:
convergence:
method: "step-halving"
metrics:
- "max_abs_diff_z: max|z_dt - z_dt2| < 1e-4"
- "rel_err_tte: |TTE_dt - TTE_dt2| / TTE_dt2 < 0.01"
feasibility:
guard: "If Delta < 0 at any rhs evaluation within RK4 stages, immediately trigger DELTA_ZERO event at current t_n."
action: "Record termination_reason = 'DELTA_ZERO' and invoke TTE_SPEC interpolation."