> ## Documentation Index
> Fetch the complete documentation index at: https://docs.plantpredict.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Battery Model

export const LGIA = () => <Tooltip tip="Large Generator Interconnection Agreement: contract defining the maximum power export limit at the point of interconnection.">
    LGIA
  </Tooltip>;

export const RoundTripEfficiencyCap = () => <Tooltip tip="Fraction of DC energy recovered during discharge relative to DC energy stored during charge; declines with cycling and aging.">
    Round-trip DC efficiency
  </Tooltip>;

export const SOC = () => <Tooltip tip="State of Charge: energy currently stored in the battery, bounded by zero (empty) and usable capacity (full).">
    SOC
  </Tooltip>;

## Summary

The battery model tracks the internal state of the energy storage system and derives the stored energy and the DC power at the battery terminals (magnitude and direction) at each timestep. It combines the charge/discharge intent from the [Dispatch Algorithms](dispatch_algorithms), the power limits from the [Charge & Discharge Limits](charge_discharge_limits), calendar and per-cycle degradation, and the previous timestep's stored energy. Unlike the rest of the PlantPredict pipeline, this model is iterative—each timestep depends on the previous timestep's state.

## Inputs

| Name                                   | Symbol           | Units    | Description                                                                                       |
| -------------------------------------- | ---------------- | -------- | ------------------------------------------------------------------------------------------------- |
| **Charge Flag**                        | $F_c$            | boolean  | True if battery should attempt to charge (from [Dispatch Algorithms](dispatch_algorithms))        |
| **Discharge Flag**                     | $F_d$            | boolean  | True if battery should attempt to discharge (from [Dispatch Algorithms](dispatch_algorithms))     |
| **Available Charge Power**             | $P_{charge}$     | W        | Maximum charge power at battery DC (from [Charge & Discharge Limits](charge_discharge_limits))    |
| **Available Discharge Power**          | $P_{discharge}$  | W        | Maximum discharge power at battery DC (from [Charge & Discharge Limits](charge_discharge_limits)) |
| **Nameplate Energy Capacity**          | $E_{nom}$        | MWh      | Total manufacturer-rated energy capacity                                                          |
| **Usable Capacity Factor**             | $f_{usable}$     | —        | Usable fraction of nameplate capacity (0 to 1)                                                    |
| **Initial Usable Energy Capacity**     | $E_{max,init}$   | MWh      | Usable energy capacity at system start                                                            |
| **Initial Round-Trip DC Efficiency**   | $\eta_{RT,init}$ | %        | DC round-trip efficiency at system start                                                          |
| **Capacity Cycle Degradation Rate**    | $d_{E,cycle}$    | %/cycle  | Capacity loss per normalized discharge cycle                                                      |
| **Capacity Calendar Degradation Rate** | $d_{E,year}$     | %/year   | Capacity loss per year of operation                                                               |
| **RTE Cycle Degradation Rate**         | $d_{\eta,cycle}$ | %/cycle  | Round-trip efficiency loss per normalized discharge cycle                                         |
| **RTE Calendar Degradation Rate**      | $d_{\eta,year}$  | %/year   | Round-trip efficiency loss per year of operation                                                  |
| **Current Timestamp**                  | $t_n$            | datetime | Timestamp at timestep $n$                                                                         |
| **Time Interval**                      | $\delta t$       | minutes  | Time interval between consecutive timestamps                                                      |

***

## Outputs

| Name                 | Symbol        | Units | Description                                                             |
| -------------------- | ------------- | ----- | ----------------------------------------------------------------------- |
| **State of Charge**  | $SOC$         | Wh    | Energy stored in battery                                                |
| **Battery DC Power** | $P_{DC,batt}$ | W     | DC power at battery terminals (positive = charge, negative = discharge) |
| **DC RTE Loss**      | $L_{\eta}$    | W     | Round-trip efficiency loss                                              |

***

## Detailed Description

The model receives dispatch intent flags and power limits from upstream, then runs in sequence:

1. **Degradation** updates the battery's capacity and efficiency parameters.
2. **<SOC /> update** adjusts stored energy based on the dispatch flags and available charge/discharge power. <RoundTripEfficiencyCap /> losses are consolidated into charging.
3. **DC power** is derived from the change in stored energy.

In the equations below, all state variables use functional notation—e.g., $SOC(t_n)$ is the state of charge at timestep $n$, and $SOC(t_{n-1})$ is its value at the previous timestep. All energy and power values are in Wh and W, respectively.

### Initial Conditions

The usable energy capacity $E_{max,init}$ is derived from the nameplate energy capacity $E_{nom}$ and a usable capacity factor $f_{usable}$ (0 to 1):

$$
E_{max,init} = E_{nom} \times f_{usable}
$$

The user specifies any two of the three values and the third is calculated automatically. $f_{usable}$ accounts for depth-of-discharge limits and reserve margins imposed by the battery manufacturer.

At the first timestep ($n = 0$), the battery is initialized to full charge with its initial parameters. $E_{max,init}$ is converted from MWh to Wh and $\eta_{RT,init}$ from percentage to fraction before use.

$$
SOC(t_0) = E_{max,init}
$$

$$
\eta_{RT}(t_0) = \eta_{RT,init}
$$

$$
P_{DC,batt}(t_0) = 0
$$

### Degradation

For all subsequent timesteps ($n \geq 1$), degradation is calculated before the SOC update so that the battery operates with its current degraded parameters. All degradation rates ($d_{E,cycle}$, $d_{E,year}$, $d_{\eta,cycle}$, $d_{\eta,year}$) are converted from percentages to fractions before use.

Two quantities degrade over time: the usable energy capacity ($D_E$ terms) and the round-trip DC efficiency ($D_\eta$ terms). Each has a cycle component—accumulated from discharge activity—and a calendar component proportional to elapsed time.

#### Cycle Degradation

Cycle degradation is applied during discharge timesteps. When the previous timestep was not a discharge, the cumulative values carry forward unchanged. During discharge, the discharged energy is normalized by the previous maximum capacity.

$$
P_{DC,batt}(t_{n-1}) \geq 0 \Rightarrow \begin{cases} D_{E,cycle}(t_n) = D_{E,cycle}(t_{n-1}) \\ D_{\eta,cycle}(t_n) = D_{\eta,cycle}(t_{n-1}) \end{cases}
$$

$$
P_{DC,batt}(t_{n-1}) < 0 \Rightarrow \begin{cases} D_{E,cycle}(t_n) = D_{E,cycle}(t_{n-1}) + \dfrac{|P_{DC,batt}(t_{n-1})|}{E_{max}(t_{n-1})} \times d_{E,cycle} \\[8pt] D_{\eta,cycle}(t_n) = D_{\eta,cycle}(t_{n-1}) + \dfrac{|P_{DC,batt}(t_{n-1})|}{E_{max}(t_{n-1})} \times d_{\eta,cycle} \end{cases}
$$

#### Calendar Degradation

Calendar degradation is proportional to the elapsed time $\Delta t$ in fractional years:

$$
\Delta t = \frac{n}{8760} \times \frac{\delta t}{60}
$$

$$
D_{E,year}(t_n) = d_{E,year} \times \Delta t
$$

$$
D_{\eta,year}(t_n) = d_{\eta,year} \times \Delta t
$$

#### Combined Degradation

Cycle and calendar degradation are summed and applied to the initial values to obtain the degraded parameters:

$$
E_{max}(t_n) = E_{max,init} \times \left(1 - D_{E,cycle}(t_n) - D_{E,year}(t_n)\right)
$$

$$
\eta_{RT}(t_n) = \eta_{RT,init} \times \left(1 - D_{\eta,cycle}(t_n) - D_{\eta,year}(t_n)\right)
$$

### State of Charge

The SOC update uses the degraded $E_{max}(t_n)$ and $\eta_{RT}(t_n)$ from above. When both charge and discharge flags are set (possible with the <LGIA /> Excess algorithm), the charge flag takes priority.

Prior to Version 12, the equations below implicitly assumed $\delta t = 60$ minutes (hourly timesteps). Sub-hourly ESS simulations were not supported and would produce erroneous results.

#### Charging

When charging ($F_c = \text{TRUE}$), the available charge power is converted to energy (multiplied by $\delta t / 60$) and scaled by the round-trip efficiency before being added to the previous SOC, capped at the degraded maximum capacity:

$$
SOC(t_n) = \min\!\left( SOC(t_{n-1}) + P_{charge} \times \frac{\delta t}{60} \times \eta_{RT}(t_n),\; E_{max}(t_n) \right)
$$

In practice, round-trip losses occur across both charge and discharge. The model lumps the entire round-trip efficiency ($\eta_{RT}$) into the charge step—the full power enters the battery but only a fraction is stored—rather than splitting losses between the two directions.

#### Discharging

When discharging ($F_c = \text{FALSE}$ and $F_d = \text{TRUE}$), energy is drawn from the battery without round-trip losses. The SOC cannot drop below zero (empty battery):

$$
SOC(t_n) = \max\!\left( SOC(t_{n-1}) - P_{discharge} \times \frac{\delta t}{60},\; 0 \right)
$$

#### Idle

When idle ($F_c = \text{FALSE}$ and $F_d = \text{FALSE}$), the SOC carries forward unchanged:

$$
SOC(t_n) = SOC(t_{n-1})
$$

### Battery DC Power

DC power is derived from the change in SOC, converting the change in stored energy back to power. $P_{DC,batt}(t_n)$ is positive during charging, negative during discharging, and zero when idle.

#### Charging

When charging ($SOC(t_n) > SOC(t_{n-1})$), the round-trip efficiency is divided out to recover the DC power that entered the battery:

$$
P_{DC,batt}(t_n) = \frac{SOC(t_n) - SOC(t_{n-1})}{\eta_{RT}(t_n) \times \delta t / 60} > 0
$$

#### Discharging

When discharging ($SOC(t_n) < SOC(t_{n-1})$), the SOC change maps directly to DC power:

$$
P_{DC,batt}(t_n) = \frac{SOC(t_n) - SOC(t_{n-1})}{\delta t / 60} < 0
$$

### Loss Reporting

Since the round-trip efficiency is applied entirely during charging, the associated loss is reported during charging timesteps ($P_{DC,batt}(t_n) > 0$):

$$
L_{\eta}(t_n) = \bigl(1 - \eta_{RT}(t_n)\bigr) \times P_{DC,batt}(t_n)
$$

***
