I’m running a PyBaMM simulation and trying to define a custom exchange current density function for the secondary positive electrode. The function works when I input values manually, but when I pass it as a parameter to PyBaMM, I get the error:
TypeError: exchange_current_density_secondary() takes 2 positional arguments but 4 were given.
When I replace exchange_current_density_secondary with a constant value, everything runs fine. But when I use the function, PyBaMM seems to call it with four arguments instead of two.
What I’ve Tried:
Checking if PyBaMM expects a function with a different signature.
Adding *args, **kwargs to capture extra arguments, but the error persists.
Printing the arguments passed to the function—PyBaMM does seem to pass extra arguments, but I don’t know why.
Questions:
How does PyBaMM internally handle functions passed as parameters?
Does the exchange current density function need a different signature for PyBaMM to use it correctly?
Has anyone faced a similar issue, and how did you solve it?
PyBaMM requires function parameters to be in a specific format. For example, the exchange current density requires four arguments: electrolyte concentration, surface concentration, maximum surface concentration and temperature. Here is an example:
def graphite_electrolyte_exchange_current_density_Ecker2015(c_e, c_s_surf, c_s_max, T):
"""
Exchange-current density for Butler-Volmer reactions between graphite and LiPF6 in
EC:DMC.
References
----------
.. [1] Ecker, Madeleine, et al. "Parameterization of a physico-chemical model of
a lithium-ion battery i. determination of parameters." Journal of the
Electrochemical Society 162.9 (2015): A1836-A1848.
.. [2] Ecker, Madeleine, et al. "Parameterization of a physico-chemical model of
a lithium-ion battery ii. model validation." Journal of The Electrochemical
Society 162.9 (2015): A1849-A1857.
.. [3] Richardson, Giles, et. al. "Generalised single particle models for
high-rate operation of graded lithium-ion electrodes: Systematic derivation
and validation." Electrochemica Acta 339 (2020): 135862
Parameters
----------
c_e : :class:`pybamm.Symbol`
Electrolyte concentration [mol.m-3]
c_s_surf : :class:`pybamm.Symbol`
Particle concentration [mol.m-3]
c_s_max : :class:`pybamm.Symbol`
Maximum particle concentration [mol.m-3]
T : :class:`pybamm.Symbol`
Temperature [K]
Returns
-------
:class:`pybamm.Symbol`
Exchange-current density [A.m-2]
"""
k_ref = 1.11 * 1e-10
# multiply by Faraday's constant to get correct units
m_ref = (
pybamm.constants.F * k_ref
) # (A/m2)(m3/mol)**1.5 - includes ref concentrations
E_r = 53400
arrhenius = pybamm.exp(-E_r / (pybamm.constants.R * T)) * pybamm.exp(
E_r / (pybamm.constants.R * 296.15)
)
return m_ref * arrhenius * c_e**0.5 * c_s_surf**0.5 * (c_s_max - c_s_surf) ** 0.5
It doesn’t matter if your function only takes two inputs; PyBaMM will reject any function that does not accept all four inputs. If there is no dependence on c_e or c_s_max, then you need to put them as inputs but then leave them unused. Many functions in PyBaMM’s ready-made parameter sets do exactly this.