Change parameter function inputs

I am currently creating a routine for parameter estimation based on experimental data. It would be helpful for me if it was possible to customize the inputs in parameter functions to align with the inputs to my parameter estimation routine.

Please let me know if there is currently a way to go about this, thank you!

Hi Derek, this notebook contains a simple example.

My PhD student wrote a much more detailed example, but it is not been tested by anyone else so far!

1 Like

Thank you @DrSOKane

I am not sure if this is exactly what I am looking for.

For example, I used a hard coded work around by editing the children in the parameter functions file:

 def j0(self, c_e, c_s_surf, T, lithiation=None):
        """Dimensional exchange-current density [A.m-2]"""
        tol = pybamm.settings.tolerances["j0__c_e"]
        c_e = pybamm.maximum(c_e, tol)
        tol = pybamm.settings.tolerances["j0__c_s"]
        c_s_surf = pybamm.maximum(
            pybamm.minimum(c_s_surf, (1 - tol) * self.c_max), tol * self.c_max
        )
        domain, Domain = self.domain_Domain
        if lithiation is None:
            lithiation = ""
        else:
            lithiation = lithiation + " "
        inputs = {
            "Electrolyte concentration [mol.m-3]": c_e,
            f"{Domain} particle surface concentration [mol.m-3]": c_s_surf,
            f"{self.phase_prefactor}Maximum {domain} particle "
            "surface concentration [mol.m-3]": self.c_max,
            "Temperature [K]": T,
        }
        return pybamm.FunctionParameter(
            f"{self.phase_prefactor}{Domain} electrode {lithiation}"
            "exchange-current density [A.m-2]",
            inputs,
        )

was edited to:

 def j0(self, c_e, c_s_surf, T, lithiation=None):
        """Dimensional exchange-current density [A.m-2]"""
        tol = pybamm.settings.tolerances["j0__c_e"]
        c_e = pybamm.maximum(c_e, tol)
        tol = pybamm.settings.tolerances["j0__c_s"]
        c_s_surf = pybamm.maximum(
            pybamm.minimum(c_s_surf, (1 - tol) * self.c_max), tol * self.c_max
        )
        domain, Domain = self.domain_Domain
        if lithiation is None:
            lithiation = ""
        else:
            lithiation = lithiation + " "
        inputs = {
            "Current [A]": pybamm.electrical_parameters.current_with_time,
        }      
         return pybamm.FunctionParameter(
            f"{self.phase_prefactor}{Domain} electrode {lithiation}"
            "exchange-current density [A.m-2]",
            inputs,
        )

Then my custom function for exchange current density in the parameter set could just be a function of Current. I was wondering if there was a more official way to go about changing the function inputs to parameter functions

Have you heard of PyBOP? It may support what you’re trying to do.

Thanks for this resource. I have looked into it a little bit today. This package is performing parameter estimation in a similar way that I want.

For some context, we have created an HMC routine that builds out GPs. We treat PyBamm as a black box model, where we supply it the GPs, which ideally could be a function of any input, to replace some battery model parameters, as well as the experimental current. PyBamm will return a Voltage which could be compared to experimental data to build out these functions in an optimizer. The end results being functions tailored to the battery.

I believe PyBOP replaces too much of the functionality we have already built into our process. Thank you for your time.

You can rename or scale any of the parameters. For example, let’s say pybamm has parameters β€œa” and β€œb”, but you want parameter β€œc” instead of β€œa” and β€œd” instead of β€œb”, where β€œd” is twice the value of β€œb”. Then you can do:

parameter_values = {"a": pybamm.InputParameter("c"), "b": pybamm.InputParameter("d")/2}

and at solve time you just specify c and d

sim.solve(inputs={"c": 1, "d": 2})