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

3.9 KiB

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 + dtk1/2, scenario.u(t_n + dt/2), params)" - "k3, _ = rhs(t_n + dt/2, x_n + dtk2/2, scenario.u(t_n + dt/2), params)" - "k4, _ = rhs(t_n + dt, x_n + dtk3, scenario.u(t_n + dt), params)" - "x_next_raw = x_n + dt(k1 + 2k2 + 2k3 + 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."