Time-dependent parameter functions (e.g. diffusivity and reaction rate from measurement data)

Hi PyBaMM team and community :waving_hand:,

I’m new to PyBaMM, but I’m very interested in the framework and am considering switching to PyBaMM for my modeling work if it can support my use case.

In my application, certain material parameters are explicitly time-dependent and are obtained from measurement data. In particular:

  • Diffusion coefficient: D(t) = Interpolation[(t_1, D_1), (t_2, D_2), …, (t_n, D_n)]

  • Reaction rate constant: k(t) = Interpolation[(t_1, k_1), (t_2, k_2), …, (t_n, k_n)]

I am currently using the following tutorial as a starting point for parameter customization:

From the tutorial, it seems that parameters such as:

  • "Positive particle diffusivity [m2.s-1]"
    take arguments like ("Positive particle stoichiometry", "Temperature [K]")

  • "Positive electrode exchange-current density [A.m-2]"
    take arguments like
    ("Electrolyte concentration [mol.m-3]", "Positive particle surface concentration [mol.m-3]", "Maximum positive particle surface concentration [mol.m-3]", "Temperature [K]")

This leads to a few questions.


Questions

1. Access to time in parameter functions

From the tutorial, my understanding is that parameter functions only receive the variables listed above (e.g. concentration, temperature, stoichiometry).
Does this mean that the time variable t is not accessible inside these parameter functions (unlike, for example, applied current functions)?

2. Framework-intended way to handle explicit time dependence

If time is not accessible in parameter functions, is there a framework-intended way to represent parameters that are explicitly time-dependent (e.g. from experimental lookup tables)?

For example:

  • Is there a way to define parameters as pybamm.Interpolant objects of time?
  • Is it possible to update or set parameter values at each time step t during the solve?

3. Overriding or extending behavior (last resort)

If neither of the above is supported, what would be the recommended method to override or extend PyBaMM to support this use case?

I would prefer to avoid overriding internal methods if possible, as that can be brittle and hard to maintain across PyBaMM version updates.

Only max. 2 links were allowed, so here is the second part:

Related discussions

I found the following posts that seem closely related, but they did not quite address my specific use case:

Hi @thegialeo, yes, you can create a time-dependent parameter using an interpolant with pybamm.t. Here’s an example using a reference electrolyte diffusivity that oscillates as a time-dependent sin wave,

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

def electrolyte_diffusivity_Nyman2008(c_e, T):
    D_c_reference = pybamm.Parameter("Diffusion coefficient reference [m2.s-1]")
    D_c_e = D_c_reference * (8.794e-11 * (c_e / 1000) ** 2 - 3.972e-10 * (c_e / 1000) + 4.862e-10)

    return D_c_e

model = pybamm.lithium_ion.DFN()

t_data = np.linspace(0, 100, 100)
D_c_reference_data = 1 + 0.5 * np.sin(t_data)
D_c_reference = pybamm.Interpolant(t_data, D_c_reference_data, pybamm.t)

parameter_values = pybamm.ParameterValues("Chen2020")
parameter_values.update({
    "Electrolyte diffusivity [m2.s-1]": electrolyte_diffusivity_Nyman2008,
    "Diffusion coefficient reference [m2.s-1]": D_c_reference,
}, check_already_exists=False)

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

sol = sim.solve([0, 100])

plt.plot(sol.t, sol["X-averaged electrolyte concentration [mol.m-3]"].data)
plt.xlabel("Time [s]")
plt.ylabel("Avg. electrolyte concentration [mol.m-3]")
plt.show()

1 Like

Thanks a lot for the fast reply and clear example. That is exactly what I was looking for. I wasn’t aware that pybamm.ParameterValues are always accessible inside parameter functions beyond the explicit arguments.