Battery & Degradation
Battery Model
The BatteryModel tracks the physical state of the battery system throughout the simulation.
Initialization
BatteryModel(
capacity_mwh=10.0, # Total energy capacity
power_mw=5.0, # Max charge/discharge power
min_soc_percent=10.0, # Minimum SoC (%)
max_soc_percent=90.0, # Maximum SoC (%)
round_trip_efficiency=0.9, # RTE as decimal (0-1)
initial_soc_percent=50.0 # Starting SoC (%)
)Efficiency Model
Round-trip efficiency (RTE) is split symmetrically into charge and discharge efficiency:
charge_efficiency = √RTE
discharge_efficiency = √RTEUse the interactive calculator below to see how RTE affects energy flow:
SoC Bounds
min_soc_mwh = capacity_mwh × min_soc_percent / 100
max_soc_mwh = capacity_mwh × max_soc_percent / 100
usable_capacity = max_soc_mwh − min_soc_mwhCharge/Discharge Limits
Maximum energy per 15-minute period:
max_charge = min(power_mw × 0.25, available_capacity / charge_efficiency)
max_discharge = min(power_mw × 0.25, stored_energy × discharge_efficiency)Where:
available_capacity = max_soc_mwh − current_soc_mwhstored_energy = current_soc_mwh − min_soc_mwh
Dynamic Updates
During simulation, the battery model is updated as degradation occurs:
update_degraded_capacity(new_capacity)— recalculates SoC boundsupdate_degraded_rte(new_rte)— recalculates one-way efficiencies
Degradation Model
The DegradationModel tracks capacity and RTE fade from two independent sources: cycling and calendar aging.
Interactive Degradation Curves
Adjust the parameters to see how different degradation rates affect battery health over a 25-year project lifetime:
Initialization
DegradationModel(
initial_capacity_mwh=10.0,
initial_rte=0.9,
degradation_per_cycle=0.00003, # Capacity fade per EFC (decimal)
degradation_per_year=0.01, # Calendar fade per year (1%)
lifetime_cycles=8000, # Cycles before replacement
rte_degradation_per_cycle=0.000004 # RTE fade per EFC (optional)
)Note
degradation_per_cycle is entered as a percentage in the API (e.g. 0.003) and divided by 100 internally.
Cycle-Based Degradation
Each cycle contributes to capacity fade, weighted by depth of discharge:
equivalent_full_cycles = energy_throughput_mwh / initial_capacity_mwh
adjusted_cycles = equivalent_full_cycles × DoD^1.5
capacity_fade = adjusted_cycles × degradation_per_cycleThe DoD exponent of 1.5 means deeper cycles degrade the battery faster:
| Depth of Discharge | Degradation Factor |
|---|---|
| 100% | 1.00× |
| 80% | 0.72× |
| 50% | 0.35× |
| 20% | 0.09× |
Calendar-Based Degradation
Time-dependent fade regardless of usage:
capacity_calendar_fade = years × degradation_per_year
rte_calendar_fade = years × degradation_per_year × 0.25Calendar aging affects RTE at 25% the rate of capacity.
RTE Degradation
If rte_degradation_per_cycle is specified:
rte_cycle_fade = total_cycles × rte_degradation_per_cycleIf not specified, RTE fades at 40% the rate of capacity:
rte_cycle_fade = capacity_cycle_fade × 0.4State of Health
SoH is tracked separately for cycle and calendar sources. The worse of the two determines overall health:
soh_capacity = 1.0 − max(capacity_cycle_fade, capacity_calendar_fade)
soh_rte = 1.0 − max(rte_cycle_fade, rte_calendar_fade)
current_capacity = initial_capacity × soh_capacity
current_rte = initial_rte × soh_rteReplacement Logic
When soh_capacity drops below 70%:
- Replacement counter increments
- Current cycle/year counters saved as new baseline
- All SoH values reset to 100%
- Future degradation calculated from the replacement point
This models a full battery swap-out when capacity drops below acceptable levels.
Degradation Tracker
SimpleDegradationTracker integrates degradation into the simulation loop:
| Property | Value |
|---|---|
| Update interval | Every 672 periods (~7 days at 15-min resolution) |
| Per update | Converts accumulated throughput to cycles, elapsed periods to years |
| Action | Calls add_cycle() and add_time(), then updates battery model |
| Finalize | Forces a final update at simulation end |
Typical Values
| Parameter | Typical Range | Description |
|---|---|---|
degradation_per_year | 0.005 - 0.02 | 0.5-2% calendar fade per year |
degradation_per_cycle | 0.001 - 0.01 | Per EFC capacity fade (API input) |
lifetime_cycles | 4,000 - 15,000 | Cycles before replacement |
| Replacement threshold | 70% SoH | Fixed |
Solar Model
Calculates actual solar generation from a production profile:
actual_generation = profile_mw × degradation_factor × availability / 100
actual_generation = min(actual_generation, peak_power_mw)Annual degradation: degradation_factor = 1.0 − degradation_rate × years_operated
Wind Model
Same calculation as solar:
actual_generation = profile_mw × degradation_factor × availability / 100
actual_generation = min(actual_generation, peak_power_mw)Both models cap output at the configured peak power (AC inverter limit).