Questions on checking sensitivities

I tried to look at the sensitivity of voltage to parameters (e.g., the diffusion coefficient of the negative electrode). The code is as follows:

import pybamm
import numpy as np

experiment = pybamm.Experiment(["Discharge at 1 C for 600 seconds",])

parameter_values = pybamm.ParameterValues('Prada2013')
parameter_values["Negative electrode diffusivity [m2.s-1]"] = "[input]"


options = {}
model = pybamm.lithium_ion.DFN(options=options)

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

inputs = {"Negative electrode diffusivity [m2.s-1]": 3e-15,}

t_eval = np.linspace(0, 1, 1000)
sim.solve(t_eval=t_eval, inputs=inputs, calculate_sensitivities=True)

I added

print(yS_out["Negative electrode diffusivity [m2.s-1]"].shape)  # (39442, 1)

in _post_process_solution function:

    def _post_process_solution(self, sol, model, integration_time, inputs_dict):
        number_of_sensitivity_parameters = self._setup[
            "number_of_sensitivity_parameters"
        ]
        sensitivity_names = self._setup["sensitivity_names"]
        number_of_timesteps = sol.t.size
        number_of_states = model.len_rhs_and_alg
        save_outputs_only = self.output_variables
        if save_outputs_only:
            # Substitute empty vectors for state vector 'y'
            y_out = np.zeros((number_of_timesteps * number_of_states, 0))
            y_event = sol.y_term
        else:
            y_out = sol.y.reshape((number_of_timesteps, number_of_states))
            y_event = y_out[-1]

        # return sensitivity solution, we need to flatten yS to
        # (#timesteps * #states (where t is changing the quickest),)
        # to match format used by Solution
        # note that yS is (n_p, n_t, n_y)
        if number_of_sensitivity_parameters != 0:
            yS_out = {
                name: sol.yS[i].reshape(-1, 1)
                for i, name in enumerate(sensitivity_names)
            }
            # add "all" stacked sensitivities ((#timesteps * #states,#sens_params))
            yS_out["all"] = np.hstack([yS_out[name] for name in sensitivity_names])
        else:
            yS_out = False
        # print(yS_out)
        # print(type(yS_out))  # <class 'dict'>
        # for key, value in yS_out.items():
        # print(key)  # Negative electrode diffusivity [m2.s-1], all
        # print(type(yS_out["Negative electrode diffusivity [m2.s-1]"]))  # <class 'numpy.ndarray'>
        # print(type(yS_out["all"]))  # <class 'numpy.ndarray'>
        print(yS_out["Negative electrode diffusivity [m2.s-1]"].shape)  # (39442, 1)
        # print(yS_out["all"].shape)  # (39442, 1)

The output is (39442, 1) as annotations in the code.

I would like to know what these 39422 numbers are and tried to decompile the .so files to find the inputs and outputs, but it is too hard for I didn’t find which is the file binded those .so files.

I need some assistance to find what compose the yS_out or how sundials idaklu solve is embeded into pybamm.

Looking forward to hearing from you. Thanks in advance。

I found more than 20 .so file linked to idaklu.cpython-39-x86_64-linux-gnu.so. It’s a hard work to get their implementations clear.

Could you provide the code used to link these files?

Hi @Azure-Dreamer, you can read the sensitivity example notebook here (Sensitivities and data fitting using PyBaMM — PyBaMM v25.1.1 Manual) if you want to learn more about how to extract the sensitivities from the solution