I am working on battery electrochemical modeling for using in microgrid applications purpose and using the pybamm functions to calculate SOC from model variables. But due to my lack of battery chemistry knowledge, I am unable to understand meaning of some features.
One specific problem I am facing is — though my cell voltage is reaching minimum, I am seeing SOC is at 40% at that time which seems not reasonable.
Here is the code:
`
import pybamm
import numpy as np
import matplotlib.pyplot as plt
def estimate_soc_from_capacity(solution):
initial_soc = 1
# Extract discharge capacity over time
discharge_capacity = solution["Discharge capacity [A.h]"].data
total_capacity = solution["Total lithium capacity [A.h]"].data[0] # Scalar value
voltage = solution["Battery open-circuit voltage [V]"].data
# Calculate SOC as an array over time
soc = initial_soc - (discharge_capacity / total_capacity)
# Extract time array
time = solution["Time [s]"].data
# Ensure time and SOC arrays have the same shape
if len(time) != len(soc):
min_length = min(len(time), len(soc))
time = time[:min_length]
soc = soc[:min_length]
return soc, time
Run PyBaMM DFN Model
import pybamm
model = pybamm.lithium_ion.DFN() # Doyle-Fuller-Newman model
parameter_values = pybamm.ParameterValues(“Chen2020”)
sim = pybamm.Simulation(model, parameter_values=parameter_values)
solution = sim.solve([0, 3600]) # Solve for 1 hour (3600 seconds)
Calculate SOC over time using capacity method
soc, time = estimate_soc_from_capacity(solution)
Get the size (number of time steps)
size = time.shape # Returns a tuple
print(f"Size of ‘Time [s]’: {size}")
import matplotlib.pyplot as plt
Extract voltage over time from solution
voltage = solution[“Terminal voltage [V]”].data
Convert time to minutes for plotting
time_minutes = time / 60
Plot SOC and Voltage vs Time
fig, ax1 = plt.subplots(figsize=(10, 5))
Primary y-axis: SOC
color_soc = “tab:blue”
ax1.set_xlabel(“Time (minutes)”)
ax1.set_ylabel(“State of Charge (%)”, color=color_soc)
ax1.plot(time_minutes, soc * 100, color=color_soc, label=“SOC (%)”)
ax1.tick_params(axis=“y”, labelcolor=color_soc)
Secondary y-axis: Voltage
ax2 = ax1.twinx()
color_voltage = “tab:red”
ax2.set_ylabel(“Terminal Voltage [V]”, color=color_voltage)
ax2.plot(time_minutes, voltage, color=color_voltage, linestyle=“–”, label=“Voltage (V)”)
ax2.tick_params(axis=“y”, labelcolor=color_voltage)
Title and grid
plt.title(“SOC and Voltage vs Time (Capacity-Based)”)
fig.tight_layout()
plt.grid(True)
plt.show()`
Let me know please if my formula looks okay and if yes, why SOC is not going close to zero?