Amplitude of the Voltage output after cycles is decreased even without aging?

Dear PyBaMM community,

I’m trying to apply a current profile on my model, after scaling up the widht to match the actual capacity of the cell. Then i noticed that the voltage output of the model is deviated after cycles and also its amplitude got decreased (As mentionned in the figure attached) even-thought the aging branch is excluded from the model.
Could someone please help me understand why this problem is happening?


This will be very apperciated.

Thank you in advance.

Code:

import pybamm
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.metrics import mean_squared_error

Set logging level

pybamm.set_logging_level(“WARNING”)

Create model

model = pybamm.lithium_ion.DFN(
options={
“cell geometry”: “pouch”,
}
)

Create parameter set

parameter_values = pybamm.ParameterValues(“OKane2022”)

Calculate total width

parameter_values.update({
# Cell geometry

    "Nominal cell capacity [A.h]": 65,
    "Electrode width [m]": 1.58 * 62/5,
    "Current function [A]": 65.0,

})

Import drive cycle

drive_cycle = pd.read_csv(
r"C:\Users\OO000009\Desktop------.csv",
comment=“#”,
header=None
).to_numpy()
drive_cycle[:, 1] = -drive_cycle[:, 1]

Load experimental data

experimental_data = pd.read_csv(r"C:\Users\OO000009\Desktop-----.csv")
exp_time_s = experimental_data[“Total Time (Seconds)”]
exp_voltage_mV = experimental_data[“Voltage (mV)”]

Convert voltage from mV to V

exp_voltage_V = exp_voltage_mV / 1000

Skip the first 3200 rows and reset time to start from 0

exp_time_s = exp_time_s.iloc[3200:].reset_index(drop=True)
exp_voltage_V = exp_voltage_V.iloc[3200:].reset_index(drop=True)
exp_time_s = exp_time_s - exp_time_s.iloc[0] # Reset time to start from 0

Create drive cycle experiment

def create_experiment(num_cycles):
# Create drive cycle step using the current function
drive_cycle_step = pybamm.step.current(drive_cycle)

# Create cycling experiment
cycle_steps = [
    (drive_cycle_step,)  # Add rest between cycles
] * num_cycles

return pybamm.Experiment(cycle_steps)

Use drive cycle experiment

experiment = create_experiment(num_cycles=100)

Solver settings

solver = pybamm.CasadiSolver(
mode=“safe”,
atol=1e-6, # Stricter tolerance
rtol=1e-6,
dt_max=600, # Smaller timestep
)

Create and run simulation

sim = pybamm.Simulation(
model,
parameter_values=parameter_values,
experiment=experiment,
solver=solver
)

print(“Starting simulation…”)
solution = sim.solve(initial_soc=0.3)

Extract data for plotting

voltage = solution[“Terminal voltage [V]”].entries
time = solution[“Time [s]”].entries

Interpolate experimental data to match simulation time points

exp_voltage_interp = np.interp(time, exp_time_s, exp_voltage_V)

Calculate RMSE between simulated and experimental voltage

rmse = np.sqrt(mean_squared_error(exp_voltage_interp, voltage))
print(f"Root Mean Squared Error (RMSE) between simulated and experimental voltage: {rmse:.4f} V")

Plot voltage comparison

plt.figure(figsize=(12, 6))
plt.plot(time, voltage, label=“Simulated Voltage”, color=“royalblue”, linewidth=2.5)
plt.plot(time, exp_voltage_interp, label=“Experimental Voltage”, color=“darkorange”, linewidth=2.5)
plt.xlabel(“Time [s]”)
plt.ylabel(“Voltage [V]”)
plt.title(“Voltage Comparison”)
plt.legend()
plt.grid(True)
plt.show()

Track capacity over cycles

cycle_numbers =
capacities =
capacity_losses =

Check if capacity data exists in solution summary variables

if “Capacity [A.h]” in solution.summary_variables:
initial_capacity = solution.summary_variables[“Capacity [A.h]”][0]
capacities = solution.summary_variables[“Capacity [A.h]”]
capacity_losses = ((initial_capacity - np.array(capacities)) / initial_capacity) * 100

# Print capacity values for each cycle
print("Cycle-wise capacities and capacity losses:")
for cycle_number, (capacity, capacity_loss) in enumerate(zip(capacities, capacity_losses), start=1):
    print(f"Cycle {cycle_number}: Capacity = {capacity:.2f} Ah, Capacity Loss = {capacity_loss:.2f} %")

# Plot results
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(10, 10))

# Capacity plot
ax1.plot(range(1, len(capacities) + 1), capacities, 'b-o')
ax1.set_xlabel('Cycle Number')
ax1.set_ylabel('Capacity [Ah]')
ax1.grid(True)
ax1.set_title('Capacity vs Cycle Number')

# Capacity loss plot
ax2.plot(range(1, len(capacities) + 1), capacity_losses, 'r-o')
ax2.set_xlabel('Cycle Number')
ax2.set_ylabel('Capacity Loss [%]')
ax2.grid(True)
ax2.set_title('Capacity Loss vs Cycle Number')

plt.tight_layout()
plt.show()

else:
print(“Capacity data is not available in the solution’s summary variables.”)

# Calculate RMSE between simulated and experimental voltage

rmse = np.sqrt(mean_squared_error(exp_voltage_interp, voltage))
print(f"Root Mean Squared Error (RMSE) between simulated and experimental voltage: {rmse:.4f} V")