pybamm-team / PyBaMM

Fast and flexible physics-based battery models in Python
https://www.pybamm.org/
BSD 3-Clause "New" or "Revised" License
1.1k stars 543 forks source link

[Bug]: Noise in low-current results using O'Kane 2022 parameter set due to graphite OCP interpolation from csv file #4365

Open tomjholland opened 2 months ago

tomjholland commented 2 months ago

PyBaMM Version

24.5

Python Version

3.11.7

Describe the bug

Differentiating low c-rate constant-current results reveals noise in calculated voltage when using "OKane2022" parameter set, but not when using "Chen2020" parameter set: image

This is due to the csv interpolation used for the graphite OCP in the "OKane2022" parameter set. The suggested fix would be to replace this with the functional form defined in "Chen2020", as the OCP curves for these parameter sets should be identical anyway.

Steps to Reproduce

The following code uses the Chen2020 parameters, OKane2022 parameters and finally the OKane2022 parameters with the graphite OCP parameter replaced with the value in the Chen2020 parameter set:

import pybamm
import numpy as np
import matplotlib.pyplot as plt

parameter_sets = ["OKane2022", "Chen2020", "OKane2022 OCP Function"]
C_rate = 0.01
plt.figure()
for parameter_set in parameter_sets:
    if parameter_set == "OKane2022 OCP Function":
        params = pybamm.ParameterValues("OKane2022")
        params["Negative electrode OCP [V]"] = pybamm.ParameterValues("Chen2020")['Negative electrode OCP [V]']
    else:
        params = pybamm.ParameterValues(parameter_set)  
    params.set_initial_stoichiometries(0)

    model = pybamm.lithium_ion.DFN()
    solver = pybamm.CasadiSolver()
    experiment = pybamm.Experiment([f"Charge at {C_rate}C until 4.2 V"])
    sim = pybamm.Simulation(
        model,
        solver=solver,
        parameter_values=params,
        experiment=experiment,
    )

    sim.solve()

    dVdQ = np.gradient(sim.solution["Terminal voltage [V]"].entries, sim.solution["Discharge capacity [A.h]"].entries)

    plt.plot(sim.solution["Discharge capacity [A.h]"].entries, dVdQ, label=parameter_set)

plt.xlabel("Capacity [Ah]")
plt.ylabel("dV/dQ [V/Ah]")
plt.legend()
plt.show()

Relevant log output

image (1)

rtimms commented 2 months ago

can you try using a linear interpolant rather than a cubic one? something like

parameter_values = pybamm.ParameterValues("Okane2022")

path = # path to where the csv is stored
graphite_LGM50_ocp_Chen2020_data = pybamm.parameters.process_1D_data(
    "graphite_LGM50_ocp_Chen2020.csv", path=path
)

def graphite_LGM50_ocp_Chen2020(sto):
    name, (x, y) = graphite_LGM50_ocp_Chen2020_data
    return pybamm.Interpolant(x, y, sto, name=name, interpolator="linear")

parameter_values["Negative electrode OCP [V]"] = graphite_LGM50_ocp_Chen2020

I think all the data interpolant OCPs should be linear, but it looks like they aren't...

kratman commented 2 months ago

can you try using a linear interpolant rather than a cubic one?

I tried this yesterday, still has the noise with linear interpolation. I also checked and several other parameter sets use cubic interpolation: image

I put a couple of my experiments below.

OKane2022 with linear

image

OKane2022 with linear and graphite_ocp_Enertech_Ai2020

image

tomjholland commented 2 months ago

can you try using a linear interpolant rather than a cubic one? something like

parameter_values = pybamm.ParameterValues("Okane2022")

path = # path to where the csv is stored
graphite_LGM50_ocp_Chen2020_data = pybamm.parameters.process_1D_data(
    "graphite_LGM50_ocp_Chen2020.csv", path=path
)

def graphite_LGM50_ocp_Chen2020(sto):
    name, (x, y) = graphite_LGM50_ocp_Chen2020_data
    return pybamm.Interpolant(x, y, sto, name=name, interpolator="linear")

parameter_values["Negative electrode OCP [V]"] = graphite_LGM50_ocp_Chen2020

I think all the data interpolant OCPs should be linear, but it looks like they aren't...

Yes so the results may be dependent on the interpolator (thanks @kratman for looking into this), my question I think is more fundamental. To my understanding:

I raised this issue to suggest that the "OKane2022" is brought in line with "Chen2020" parameter set to use the fitted function form for consistency, although I realise that this is not a general solution for the other parameter sets that just use interpolation.

kratman commented 2 months ago

Yeah I used the Ai2020 data to show that something was specifically an issue with the data set used by OKane2022. It could be as simple as not having enough resolution to make the function smooth

kratman commented 2 months ago

@DrSOKane Can you take a look at this?