Half-cell OCP fitting

In this example, we show how to fit the half-cell Open-Circuit Potential to pseudo-OCP data. Our recommended workflow for fitting OCPs is to first fit the MSMR model to the data and then create an interpolant to find a function \(U(x)\), where \(x\) is the stoichiometry. For comparison, we also show how to fit a function \(U(x)\) directly to pseudo-OCP data.

import ionworkspipeline as iwp
import numpy as np
import pandas as pd
import pybamm
import matplotlib.pyplot as plt
from scipy.signal import savgol_filter

Pre-process and visualize the data

First, we load and pre-process the data.

# Load data
raw_ocp_data = pd.read_csv("anode_ocp_delithiation.csv", comment="#")
q = raw_ocp_data["Capacity [A.h]"].values
U = raw_ocp_data["Voltage [V]"].values

# Smooth
q_smoothed = savgol_filter(q, window_length=11, polyorder=1)
U_smoothed = savgol_filter(U, window_length=11, polyorder=1)
dQdU_smoothed = -np.gradient(q_smoothed, U_smoothed)

# Store in a dataframe
ocp_data = pd.DataFrame({"Capacity [A.h]": q_smoothed, "Voltage [V]": U_smoothed})
ocp_data = iwp.data_fits.preprocess.sort_capacity_and_ocp(ocp_data)
# Maximum capacity, will be used later as an initial guess for the electrode capacity
Q_max_data = ocp_data["Capacity [A.h]"].max()

# Plot
_, ax = plt.subplots(1, 2, figsize=(10, 5))
ax[0].plot(q_smoothed, U_smoothed, "-x")
ax[0].set_xlabel("Capacity [A.h]")
ax[0].set_ylabel("Voltage [V]")
ax[1].plot(dQdU_smoothed, U_smoothed, "-x")
ax[1].set_xlabel("dQ/dU [A.h/V]")
ax[1].set_ylabel("Voltage [V]")
ax[1].set_xlim(0, 200)
plt.tight_layout()
/home/docs/checkouts/readthedocs.org/user_builds/ionworks-ionworkspipeline/envs/v0.6.6/lib/python3.12/site-packages/numpy/lib/function_base.py:1242: RuntimeWarning: divide by zero encountered in divide
  a = -(dx2)/(dx1 * (dx1 + dx2))
/home/docs/checkouts/readthedocs.org/user_builds/ionworks-ionworkspipeline/envs/v0.6.6/lib/python3.12/site-packages/numpy/lib/function_base.py:1243: RuntimeWarning: divide by zero encountered in divide
  b = (dx2 - dx1) / (dx1 * dx2)
/home/docs/checkouts/readthedocs.org/user_builds/ionworks-ionworkspipeline/envs/v0.6.6/lib/python3.12/site-packages/numpy/lib/function_base.py:1244: RuntimeWarning: divide by zero encountered in divide
  c = dx1 / (dx2 * (dx1 + dx2))
/home/docs/checkouts/readthedocs.org/user_builds/ionworks-ionworkspipeline/envs/v0.6.6/lib/python3.12/site-packages/numpy/lib/function_base.py:1250: RuntimeWarning: invalid value encountered in add
  out[tuple(slice1)] = a * f[tuple(slice2)] + b * f[tuple(slice3)] + c * f[tuple(slice4)]
../../../_images/fee1a0d719068a3ea890ca655817cf73742bb13718328f40210c60198198a2a8.png

Fit the MSMR model to data

We begin by setting up initial guesses for our MSMR parameters.

# Initial guess of Graphite from Verbrugge et al 2017 J. Electrochem. Soc. 164 E3243
msmr_param_init = {
    "U0_p_0": 0.088,
    "X_p_0": 0.43,
    "w_p_0": 0.086,
    "U0_p_1": 0.13,
    "X_p_1": 0.24,
    "w_p_1": 0.080,
    "U0_p_2": 0.14,
    "X_p_2": 0.15,
    "w_p_2": 0.72,
    "U0_p_3": 0.17,
    "X_p_3": 0.055,
    "w_p_3": 2.5,
    "U0_p_4": 0.21,
    "X_p_4": 0.067,
    "w_p_4": 0.095,
    "U0_p_5": 0.36,
    "X_p_5": 0.055,
    "w_p_5": 6.0,
    "Number of reactions in positive electrode": 6,
    "Positive electrode lower excess capacity [A.h]": 0.0,
    "Positive electrode capacity [A.h]": Q_max_data,
    "Ambient temperature [K]": 298.15,
}

We can plot these against the data and, if required, manually adjust them to get a better starting point. For this example, let’s keep the Graphite parameters as our initial guess.

fig, ax = iwp.objectives.plot_each_species_msmr(
    ocp_data, msmr_param_init, "positive", voltage_limits=(0, 1.5)
)
ax[1].set_xlim(0, 50)
(0.0, 50.0)
../../../_images/d88167c2cd2eba5d44309fb881001e8c6a3b8257412b7987e9c566b58601ba60.png

Now we can set up the objective and parameters to fit, run the data fit and plot the results.

# Fit the electrode capacity and lower excess capacity by making them Parameter objects
msmr_params = {
    "Positive electrode capacity [A.h]": iwp.Parameter(
        "Q", initial_value=Q_max_data, bounds=(0.9 * Q_max_data, 1.2 * Q_max_data)
    ),
    "Positive electrode lower excess capacity [A.h]": (
        iwp.Parameter(
            "Q_lowex", initial_value=0.01 * Q_max_data, bounds=(0, 0.01 * Q_max_data)
        )
    ),
}
# Add Parameter objects for the MSMR parameters X_j, U0_j, and w_j
for k, v in msmr_param_init.items():
    if "X" in k:
        bounds = (0, 1)
    elif "U0_" in k:
        # allow a 500 mV variation either way
        bounds = (max(0, v - 0.5), v + 0.5)
    elif "w_" in k:
        bounds = (1e-2, 100)
    else:
        continue
    msmr_params[k] = iwp.Parameter(k, initial_value=v, bounds=bounds)

# Calculate dUdQ cutoff to prevent overfitting to extreme dUdQ values
dUdq_cutoff = iwp.data_fits.util.calculate_dUdQ_cutoff(ocp_data)

# Set up model, objective and fit
model = iwp.data_fits.models.MSMRHalfCellModel(
    "positive", options={"species format": "Xj"}
)
objective = iwp.data_fits.objectives.MSMRHalfCell(
    ocp_data, options={"model": model, "dUdQ cutoff": dUdq_cutoff}
)
ocp_msmr = iwp.DataFit(objective, parameters=msmr_params)

# Run the fit
results = ocp_msmr.run({"Ambient temperature [K]": 298.15})

# Plot results
fig_ax = ocp_msmr.plot_fit_results()
axes = fig_ax["MSMRHalfCell"][0][1]
_ = axes[2].set_xlim(0, 100)
/home/docs/checkouts/readthedocs.org/user_builds/ionworks-ionworkspipeline/envs/v0.6.6/lib/python3.12/site-packages/pybamm/expression_tree/binary_operators.py:260: RuntimeWarning: overflow encountered in square
  return left**right
../../../_images/c763325692d1f3a2fab6825b705b4479cf711cd121df0400bfff4a590ae80820.png

Lastly, we can look at the fitted parameters.

results
Result(
  Positive electrode capacity [A.h]: 5.70903
  Positive electrode lower excess capacity [A.h]: 0.0473708
  U0_p_0: 0.0923044
  X_p_0: 0.201729
  w_p_0: 0.0193839
  U0_p_1: 0.132873
  X_p_1: 0.154739
  w_p_1: 0.039704
  U0_p_2: 0.21719
  X_p_2: 0.0513561
  w_p_2: 0.19392
  U0_p_3: 0.143767
  X_p_3: 0.117637
  w_p_3: 0.532067
  U0_p_4: 0.0920261
  X_p_4: 0.109866
  w_p_4: 0.116843
  U0_p_5: 0.101949
  X_p_5: 0.395303
  w_p_5: 5.83116
)
results.callbacks["MSMRHalfCell"].callbacks[0].fit_results_["outputs"]
{'Voltage [V]': array([0.57042509, 0.55625879, 0.54209249, 0.52792619, 0.51375989,
        0.49959359, 0.48648957, 0.47295495, 0.46045517, 0.44915866,
        0.43675264, 0.42406013, 0.41270112, 0.40113721, 0.39000913,
        0.37774201, 0.36722685, 0.35521324, 0.34456959, 0.33331822,
        0.32313643, 0.31454164, 0.30540338, 0.2967374 , 0.28874685,
        0.28124941, 0.27411313, 0.26702894, 0.26037709, 0.25435727,
        0.2486604 , 0.24312153, 0.23816607, 0.23433054, 0.23066864,
        0.22734184, 0.22472   , 0.22253744, 0.22104247, 0.22010138,
        0.21935997, 0.21880088, 0.2183286 , 0.2178459 , 0.21732327,
        0.21679716, 0.2160245 , 0.21504521, 0.21366136, 0.21194241,
        0.20987445, 0.20766585, 0.20530271, 0.20272775, 0.19990449,
        0.19689023, 0.1936763 , 0.19042243, 0.18722066, 0.18420119,
        0.1813189 , 0.17866233, 0.1761325 , 0.17363741, 0.17126907,
        0.16905526, 0.1669873 , 0.16509297, 0.16329762, 0.16157692,
        0.15996041, 0.15830917, 0.15676558, 0.15520289, 0.15365235,
        0.1521296 , 0.15061032, 0.14913097, 0.14770024, 0.14644488,
        0.14522251, 0.14403487, 0.14302085, 0.14203462, 0.14115778,
        0.14040769, 0.13969059, 0.13896828, 0.13829285, 0.13772334,
        0.13718161, 0.13674926, 0.13624226, 0.13586547, 0.13546959,
        0.13515358, 0.13483757, 0.13466741, 0.1345285 , 0.13442259,
        0.13429237, 0.13414304, 0.13400414, 0.1339642 , 0.1338878 ,
        0.13382182, 0.13368986, 0.13354054, 0.13331135, 0.13323668,
        0.13318807, 0.13305263, 0.13296755, 0.13284775, 0.13285295,
        0.13276961, 0.1327453 , 0.13266717, 0.13260639, 0.13255257,
        0.13245533, 0.13232337, 0.13233726, 0.13227302, 0.13226781,
        0.13208203, 0.13200042, 0.13192055, 0.13177643, 0.13174518,
        0.13159412, 0.1314257 , 0.13134235, 0.13110621, 0.13087876,
        0.13058358, 0.13036307, 0.13005574, 0.12960256, 0.12914243,
        0.1286198 , 0.1280555 , 0.12725679, 0.1262341 , 0.1250152 ,
        0.12335007, 0.12166063, 0.12012919, 0.11810117, 0.11562517,
        0.11317522, 0.11070617, 0.10817288, 0.10582017, 0.1036515 ,
        0.10194296, 0.10062336, 0.09939057, 0.09774106, 0.09668017,
        0.09637284, 0.09584326, 0.09548037, 0.09543002, 0.09532063,
        0.09513311, 0.09471118, 0.09449067, 0.09411736, 0.09405659,
        0.0938899 , 0.09374058, 0.0938899 , 0.09378225, 0.09352006,
        0.09342804, 0.09335511, 0.09337942, 0.0932683 , 0.0932492 ,
        0.09321794, 0.09334122, 0.09315891, 0.09299222, 0.0929436 ,
        0.09300264, 0.09291061, 0.09285158, 0.09280817, 0.09277518,
        0.0927665 , 0.0926901 , 0.09255293, 0.09251994, 0.0924939 ,
        0.09249563, 0.09237236, 0.09237409, 0.09238798, 0.09233242,
        0.09235152, 0.09235499, 0.0923411 , 0.09235847, 0.09233589,
        0.09230985, 0.0922022 , 0.09218136, 0.09216573, 0.0921258 ,
        0.09208934, 0.09203204, 0.09202336, 0.0920303 , 0.09196779,
        0.09198689, 0.09192091, 0.09190876, 0.09186188, 0.09179763,
        0.09180458, 0.09186188, 0.09175075, 0.09168477, 0.09168651,
        0.09162053, 0.09150072, 0.09143474, 0.09138439, 0.0913323 ,
        0.09127674, 0.09111526, 0.09104928, 0.09092947, 0.09077147,
        0.09066208, 0.09052491, 0.09039121, 0.09016376, 0.08997971,
        0.08973488, 0.08936331, 0.0890282 , 0.08862017, 0.08808017,
        0.08741863, 0.08661298, 0.08549305, 0.08441167, 0.08333029,
        0.08224891, 0.08116752, 0.08008614]),
 'Capacity [A.h]': array([0.04743309, 0.05640264, 0.06617624, 0.07681725, 0.08839231,
        0.10097119, 0.11356357, 0.12759976, 0.14154994, 0.15501882,
        0.17080249, 0.18807921, 0.20455471, 0.22235405, 0.24049855,
        0.26169742, 0.28090052, 0.30404058, 0.32563814, 0.34961293,
        0.37233907, 0.39229434, 0.41429247, 0.43590134, 0.45647308,
        0.47634122, 0.49576366, 0.51554529, 0.53459848, 0.55230863,
        0.56966058, 0.58758798, 0.60565208, 0.62257862, 0.6435883 ,
        0.66986601, 0.69771794, 0.72673588, 0.74968123, 0.76524877,
        0.77801402, 0.78787261, 0.79631983, 0.80503481, 0.81452669,
        0.82409909, 0.83809987, 0.85556095, 0.87925824, 0.90638545,
        0.93489991, 0.96028459, 0.9824027 , 1.00201422, 1.01995896,
        1.036792  , 1.05359199, 1.0704608 , 1.08762676, 1.10478573,
        1.12237176, 1.13987067, 1.1578883 , 1.1771365 , 1.19692547,
        1.21689023, 1.23691702, 1.25649471, 1.276178  , 1.29609517,
        1.31575034, 1.33676295, 1.3572389 , 1.37875344, 1.4008333 ,
        1.42316764, 1.44602119, 1.46874197, 1.49107328, 1.51088905,
        1.53032387, 1.54928769, 1.56551222, 1.58131466, 1.59541187,
        1.60757776, 1.61943848, 1.63189272, 1.6444997 , 1.65651729,
        1.67004786, 1.68323016, 1.70292481, 1.72189686, 1.74744972,
        1.77323524, 1.80496215, 1.82487523, 1.84273073, 1.85735416,
        1.8765628 , 1.90028194, 1.92396931, 1.93106518, 1.94498824,
        1.95737324, 1.98310415, 2.01365541, 2.06306495, 2.07969106,
        2.09062761, 2.12145131, 2.1410011 , 2.16863246, 2.16743085,
        2.18664181, 2.19223339, 2.2101448 , 2.22398779, 2.23616492,
        2.25791388, 2.28679031, 2.2837903 , 2.29757913, 2.29868729,
        2.33713843, 2.3533088 , 2.36867147, 2.39516701, 2.40069824,
        2.42632153, 2.45269254, 2.46488487, 2.49641823, 2.52278266,
        2.5516857 , 2.56983105, 2.59096428, 2.6150928 , 2.6333216 ,
        2.64888728, 2.66178145, 2.67603986, 2.69084806, 2.70625189,
        2.72554289, 2.74389954, 2.75968747, 2.7794571 , 2.80198538,
        2.82277004, 2.84257723, 2.86240004, 2.88153688, 2.9016993 ,
        2.92139166, 2.94063094, 2.96337982, 3.00403944, 3.03825483,
        3.04959253, 3.07094033, 3.08722227, 3.08961687, 3.09495438,
        3.10460128, 3.12953235, 3.14528517, 3.1794381 , 3.18628156,
        3.20762202, 3.23068234, 3.20762191, 3.22381445, 3.27376116,
        3.29570064, 3.31503628, 3.30838885, 3.34052434, 3.34651394,
        3.3566252 , 3.3189285 , 3.37680518, 3.44183078, 3.46311859,
        3.43740717, 3.47816805, 3.5063091 , 3.52797544, 3.54497993,
        3.54953001, 3.59087283, 3.67033017, 3.69027346, 3.70620232,
        3.70513592, 3.78213657, 3.78103846, 3.77226498, 3.80744095,
        3.7953273 , 3.79312681, 3.80193261, 3.79092704, 3.80523697,
        3.82177133, 3.88993709, 3.90301815, 3.91278979, 3.9375775 ,
        3.95993375, 3.99441542, 3.99956187, 3.99544666, 4.03194864,
        4.02092713, 4.05846927, 4.06521539, 4.09070581, 4.12420027,
        4.12066224, 4.09070581, 4.1475408 , 4.17875834, 4.17796142,
        4.20728894, 4.25558783, 4.27952837, 4.29658116, 4.31315716,
        4.32969762, 4.37166208, 4.38646433, 4.41035258, 4.43685068,
        4.45246051, 4.4694958 , 4.48390192, 4.5046512 , 4.51890413,
        4.53544056, 4.55706449, 4.57427183, 4.59328492, 4.61603113,
        4.64082487, 4.66697803, 4.69679274, 4.7194694 , 4.7373622 ,
        4.75157613, 4.76303639, 4.7724737 ]),
 'Differential voltage [V/Ah]': array([0.38529092, 0.37519915, 0.36580181, 0.35691117, 0.34809901,
        0.3383097 , 0.32462326, 0.30043813, 0.25893831, 0.20573024,
        0.15821355, 0.12509225, 0.10070089, 0.08405313, 0.07434117,
        0.06657485, 0.06140016, 0.05809507, 0.0560296 , 0.05508752,
        0.05513776, 0.05618581, 0.05835726, 0.06166742, 0.0663692 ,
        0.07380933, 0.08337864, 0.09617428, 0.11521073, 0.13906561,
        0.16494031, 0.18560653, 0.1936211 , 0.18932942, 0.17875967,
        0.16590169, 0.1529236 , 0.14080084, 0.129899  , 0.12025959,
        0.11182327, 0.10448109, 0.09810438, 0.09258264, 0.08779358,
        0.08363568, 0.08003406, 0.07689683, 0.07421808, 0.07190958,
        0.06992045, 0.06821415, 0.06676499, 0.0655471 , 0.06455101,
        0.06379954, 0.06322452, 0.0628319 , 0.06259885, 0.06247456,
        0.06233771, 0.06168202, 0.05957509, 0.05354517, 0.04386254,
        0.03346208, 0.02551468, 0.01982442, 0.01607834, 0.01329714,
        0.01141597, 0.01007635, 0.00890855, 0.00806701, 0.00740125,
        0.00686704, 0.00642271, 0.00604474, 0.00573871, 0.00547527,
        0.00525253, 0.00507001, 0.00491414, 0.00477364, 0.00467601,
        0.00457839, 0.00449344, 0.00443234, 0.0043917 , 0.00435759,
        0.00434045, 0.00433493, 0.00434313, 0.00436549, 0.00439979,
        0.00445023, 0.00451391, 0.00459695, 0.00469313, 0.00482355,
        0.00495656, 0.00512091, 0.00532311, 0.00555817, 0.00584138,
        0.00616539, 0.0065678 , 0.0070418 , 0.00766594, 0.00839378,
        0.0092794 , 0.01058323, 0.01216063, 0.01447365, 0.01785759,
        0.02260294, 0.03056743, 0.04326925, 0.06018944, 0.07541441,
        0.08446623, 0.09061481, 0.0960811 , 0.10194362, 0.1083521 ,
        0.1151687 , 0.12194908, 0.12715134, 0.12705294, 0.11760383,
        0.09958925, 0.0802783 , 0.06418594, 0.05251043, 0.04439295,
        0.03808855, 0.03295339, 0.02934863, 0.02624157, 0.02368167,
        0.02115409, 0.01849577, 0.01574289, 0.01310959, 0.01100331,
        0.00898888, 0.00760241, 0.00502415, 0.00440939, 0.00397968,
        0.00362836, 0.003346  , 0.00309779, 0.00289566, 0.00259292,
        0.00245118, 0.00232417, 0.002138  , 0.00206096, 0.00199266,
        0.00193183, 0.00188006, 0.00183337, 0.00179066, 0.00175914,
        0.00172763, 0.00169612, 0.00166502, 0.00164345, 0.00161364,
        0.00160151, 0.00158084, 0.00157462, 0.00157873, 0.00158285,
        0.00158697, 0.00159323, 0.00160457, 0.00161862, 0.00163582,
        0.00165682, 0.00167949, 0.00170667, 0.00173712, 0.00177323,
        0.00181216, 0.00185772, 0.00190958, 0.0019647 , 0.00210497,
        0.00218455, 0.00228087, 0.0023932 , 0.00252033, 0.00264746,
        0.00281258, 0.00322185, 0.00348524, 0.00384199, 0.00419873,
        0.00465287, 0.00525521, 0.00602024, 0.00692749, 0.00813357,
        0.00963795, 0.01153764, 0.01369993, 0.01605065, 0.01835402,
        0.02048955, 0.02251661, 0.02464362, 0.02714684, 0.03023259,
        0.03404223, 0.03972411, 0.0473563 , 0.0585433 , 0.07630772,
        0.10455632]),
 'Full voltage [V]': array([0.08008614, 0.08013518, 0.08018422, ..., 0.57032701, 0.57037605,
        0.57042509]),
 'Full capacity [A.h]': array([4.7724737 , 4.77208111, 4.77168548, ..., 0.04749256, 0.04746282,
        0.04743309]),
 'Full differential capacity [Ah/V]': array([6.06213014e-01, 6.60814844e-01, 7.19769524e-01, 7.83313918e-01,
        8.51675565e-01, 9.25067094e-01, 9.97599908e-01, 1.07734374e+00,
        1.15544422e+00, 1.22975782e+00, 1.31547757e+00, 1.40761665e+00,
        1.49383807e+00, 1.58518324e+00, 1.67637109e+00, 1.78044290e+00,
        1.87242321e+00, 1.98036591e+00, 2.07826110e+00, 2.18371320e+00,
        2.28055954e+00, 2.36311762e+00, 2.45147512e+00, 2.53562586e+00,
        2.61341740e+00, 2.68661592e+00, 2.75683145e+00, 2.82845069e+00,
        2.90202386e+00, 2.98684482e+00, 3.11870132e+00, 3.39353254e+00,
        3.98086373e+00, 4.95293982e+00, 6.68961546e+00, 9.28802599e+00,
        1.20429308e+01, 1.45429053e+01, 1.61143288e+01, 1.69434348e+01,
        1.74710539e+01, 1.77818731e+01, 1.79801289e+01, 1.81182740e+01,
        1.81916988e+01, 1.81843801e+01, 1.80273000e+01, 1.75914923e+01,
        1.65903271e+01, 1.49140116e+01, 1.26544627e+01, 1.03867149e+01,
        8.42451042e+00, 6.91262101e+00, 5.89659886e+00, 5.34738366e+00,
        5.16151389e+00, 5.24333946e+00, 5.50500503e+00, 5.87957212e+00,
        6.33937390e+00, 6.84821392e+00, 7.40824839e+00, 8.03238412e+00,
        8.68900801e+00, 9.35563234e+00, 1.00190054e+01, 1.06546321e+01,
        1.12744070e+01, 1.18763160e+01, 1.24407895e+01, 1.30074228e+01,
        1.35192654e+01, 1.40107851e+01, 1.44628384e+01, 1.48634438e+01,
        1.52120835e+01, 1.54954504e+01, 1.57113098e+01, 1.58505811e+01,
        1.59406222e+01, 1.59888627e+01, 1.60104283e+01, 1.60411308e+01,
        1.61301887e+01, 1.63390831e+01, 1.68010592e+01, 1.78096529e+01,
        1.97382651e+01, 2.27431661e+01, 2.76281590e+01, 3.37580627e+01,
        4.47416839e+01, 5.65675782e+01, 7.33389842e+01, 9.04262010e+01,
        1.10925344e+02, 1.23265054e+02, 1.33897540e+02, 1.42268601e+02,
        1.52770073e+02, 1.64917775e+02, 1.76100713e+02, 1.79260557e+02,
        1.85200756e+02, 1.90191826e+02, 1.99664988e+02, 2.09314370e+02,
        2.21175629e+02, 2.24113115e+02, 2.25753911e+02, 2.29128844e+02,
        2.30310490e+02, 2.30708061e+02, 2.30721796e+02, 2.30164150e+02,
        2.29866344e+02, 2.28501316e+02, 2.27017471e+02, 2.25403503e+02,
        2.21803614e+02, 2.15608602e+02, 2.16327088e+02, 2.12881786e+02,
        2.12589057e+02, 2.00981844e+02, 1.95265682e+02, 1.89383133e+02,
        1.78217681e+02, 1.75726113e+02, 1.63475186e+02, 1.49682624e+02,
        1.42915549e+02, 1.24338714e+02, 1.07726390e+02, 8.85979725e+01,
        7.62554507e+01, 6.17876614e+01, 4.56430453e+01, 3.43206528e+01,
        2.58913870e+01, 2.02814106e+01, 1.59354591e+01, 1.33819698e+01,
        1.20671195e+01, 1.11867315e+01, 1.05634801e+01, 1.00610685e+01,
        9.44405563e+00, 8.76973513e+00, 8.22198852e+00, 7.86458546e+00,
        7.87099952e+00, 8.54608034e+00, 1.02918529e+01, 1.30136603e+01,
        1.63587691e+01, 2.07768643e+01, 2.89732133e+01, 3.57612343e+01,
        3.80575449e+01, 4.27839928e+01, 4.71878247e+01, 4.79300946e+01,
        4.96958125e+01, 5.33397415e+01, 6.62155899e+01, 7.73446899e+01,
        1.08996710e+02, 1.16351117e+02, 1.40830308e+02, 1.69145716e+02,
        1.40830186e+02, 1.60564222e+02, 2.24464929e+02, 2.52891337e+02,
        2.77732221e+02, 2.69226184e+02, 3.09897391e+02, 3.17332733e+02,
        3.29761821e+02, 2.82692859e+02, 3.54061857e+02, 4.26950930e+02,
        4.48786875e+02, 4.22281320e+02, 4.63571544e+02, 4.89715414e+02,
        5.08471277e+02, 5.22334054e+02, 5.25913832e+02, 5.55889984e+02,
        6.00270063e+02, 6.08618143e+02, 6.14471320e+02, 6.14102119e+02,
        6.32354995e+02, 6.32214928e+02, 6.30970607e+02, 6.34615858e+02,
        6.33764823e+02, 6.33564631e+02, 6.34281552e+02, 6.33350495e+02,
        6.34492641e+02, 6.35073882e+02, 6.29112850e+02, 6.26433463e+02,
        6.24110360e+02, 6.16986852e+02, 6.09053839e+02, 5.94032477e+02,
        5.91502442e+02, 5.93531483e+02, 5.73879092e+02, 5.80204919e+02,
        5.57281738e+02, 5.52752205e+02, 5.34524550e+02, 5.07941882e+02,
        5.10888775e+02, 5.34524550e+02, 4.87694350e+02, 4.58474861e+02,
        4.59250458e+02, 4.29717586e+02, 3.76894830e+02, 3.48973769e+02,
        3.28473493e+02, 3.08118669e+02, 2.87450390e+02, 2.33969457e+02,
        2.14993068e+02, 1.84651504e+02, 1.52079437e+02, 1.33864795e+02,
        1.15235657e+02, 1.00821399e+02, 8.28056175e+01, 7.26097536e+01,
        6.31118759e+01, 5.40816732e+01, 4.89345591e+01, 4.44821786e+01,
        3.99188594e+01, 3.51310679e+01, 2.98859855e+01, 2.35522453e+01,
        1.85763852e+01, 1.46875569e+01, 1.17436530e+01, 9.56423071e+00,
        7.97499349e+00]),
 'Full differential voltage [V/Ah]': array([1.64958517e+00, 1.51328320e+00, 1.38933362e+00, 1.27662739e+00,
        1.17415603e+00, 1.08100267e+00, 1.00240587e+00, 9.28208859e-01,
        8.65468002e-01, 8.13168237e-01, 7.60180201e-01, 7.10420698e-01,
        6.69416597e-01, 6.30841897e-01, 5.96526631e-01, 5.61658002e-01,
        5.34067296e-01, 5.04957188e-01, 4.81171495e-01, 4.57935593e-01,
        4.38488880e-01, 4.23169795e-01, 4.07917662e-01, 3.94379950e-01,
        3.82640752e-01, 3.72215468e-01, 3.62735270e-01, 3.53550445e-01,
        3.44587105e-01, 3.34801457e-01, 3.20646288e-01, 2.94678182e-01,
        2.51201766e-01, 2.01900293e-01, 1.49485423e-01, 1.07665504e-01,
        8.30362658e-02, 6.87620515e-02, 6.20565717e-02, 5.90199101e-02,
        5.72375315e-02, 5.62370452e-02, 5.56169538e-02, 5.51928954e-02,
        5.49701273e-02, 5.49922512e-02, 5.54714238e-02, 5.68456605e-02,
        6.02760870e-02, 6.70510410e-02, 7.90235054e-02, 9.62768313e-02,
        1.18701260e-01, 1.44662929e-01, 1.69589288e-01, 1.87007341e-01,
        1.93741608e-01, 1.90718150e-01, 1.81652877e-01, 1.70080404e-01,
        1.57744284e-01, 1.46023476e-01, 1.34984675e-01, 1.24496038e-01,
        1.15087936e-01, 1.06887484e-01, 9.98103067e-02, 9.38558917e-02,
        8.86964606e-02, 8.42011954e-02, 8.03807511e-02, 7.68791803e-02,
        7.39685161e-02, 7.13735876e-02, 6.91427210e-02, 6.72791591e-02,
        6.57372149e-02, 6.45350716e-02, 6.36484173e-02, 6.30891696e-02,
        6.27328087e-02, 6.25435352e-02, 6.24592910e-02, 6.23397448e-02,
        6.19955551e-02, 6.12029449e-02, 5.95200568e-02, 5.61493257e-02,
        5.06630141e-02, 4.39692519e-02, 3.61949560e-02, 2.96225530e-02,
        2.23505222e-02, 1.76779709e-02, 1.36353129e-02, 1.10587417e-02,
        9.01507235e-03, 8.11259935e-03, 7.46839713e-03, 7.02895787e-03,
        6.54578465e-03, 6.06362778e-03, 5.67856871e-03, 5.57847201e-03,
        5.39954601e-03, 5.25784951e-03, 5.00838936e-03, 4.77750286e-03,
        4.52129380e-03, 4.46203249e-03, 4.42960210e-03, 4.36435668e-03,
        4.34196462e-03, 4.33448227e-03, 4.33422423e-03, 4.34472528e-03,
        4.35035413e-03, 4.37634241e-03, 4.40494731e-03, 4.43648828e-03,
        4.50849281e-03, 4.63803387e-03, 4.62262959e-03, 4.69744273e-03,
        4.70391098e-03, 4.97557382e-03, 5.12122760e-03, 5.28030129e-03,
        5.61111555e-03, 5.69067388e-03, 6.11713635e-03, 6.68080218e-03,
        6.99713925e-03, 8.04254737e-03, 9.28277649e-03, 1.12869400e-02,
        1.31138167e-02, 1.61844611e-02, 2.19091429e-02, 2.91369749e-02,
        3.86228826e-02, 4.93062350e-02, 6.27531339e-02, 7.47274142e-02,
        8.28698180e-02, 8.93916156e-02, 9.46657721e-02, 9.93930218e-02,
        1.05886712e-01, 1.14028529e-01, 1.21625079e-01, 1.27152283e-01,
        1.27048667e-01, 1.17012708e-01, 9.71642338e-02, 7.68423318e-02,
        6.11292938e-02, 4.81304584e-02, 3.45146391e-02, 2.79632406e-02,
        2.62759987e-02, 2.33732275e-02, 2.11919071e-02, 2.08637185e-02,
        2.01224198e-02, 1.87477474e-02, 1.51021837e-02, 1.29291358e-02,
        9.17458887e-03, 8.59467471e-03, 7.10074426e-03, 5.91206223e-03,
        7.10075042e-03, 6.22803753e-03, 4.45503894e-03, 3.95426753e-03,
        3.60059051e-03, 3.71434898e-03, 3.22687454e-03, 3.15126647e-03,
        3.03249174e-03, 3.53740806e-03, 2.82436523e-03, 2.34218953e-03,
        2.22822916e-03, 2.36808960e-03, 2.15716433e-03, 2.04200230e-03,
        1.96667943e-03, 1.91448364e-03, 1.90145218e-03, 1.79891710e-03,
        1.66591683e-03, 1.64306636e-03, 1.62741526e-03, 1.62839366e-03,
        1.58139021e-03, 1.58174057e-03, 1.58485988e-03, 1.57575640e-03,
        1.57787236e-03, 1.57837094e-03, 1.57658692e-03, 1.57890459e-03,
        1.57606241e-03, 1.57461994e-03, 1.58953994e-03, 1.59633873e-03,
        1.60228073e-03, 1.62078008e-03, 1.64189097e-03, 1.68340964e-03,
        1.69061010e-03, 1.68483059e-03, 1.74252733e-03, 1.72352899e-03,
        1.79442449e-03, 1.80912892e-03, 1.87082146e-03, 1.96872917e-03,
        1.95737321e-03, 1.87082146e-03, 2.05046460e-03, 2.18114467e-03,
        2.17746109e-03, 2.32710978e-03, 2.65326006e-03, 2.86554489e-03,
        3.04438568e-03, 3.24550279e-03, 3.47886117e-03, 4.27406216e-03,
        4.65131276e-03, 5.41560711e-03, 6.57551092e-03, 7.47022397e-03,
        8.67786955e-03, 9.91852926e-03, 1.20764754e-02, 1.37722544e-02,
        1.58448784e-02, 1.84905522e-02, 2.04354554e-02, 2.24809133e-02,
        2.50508160e-02, 2.84648335e-02, 3.34604994e-02, 4.24587969e-02,
        5.38317864e-02, 6.80848427e-02, 8.51523795e-02, 1.04556240e-01,
        1.25391952e-01])}

We can access tabulated capacity vs OCP data from the MSMR callback

outputs = results.callbacks["MSMRHalfCell"].callbacks[0].fit_results_["outputs"]
q = outputs["Capacity [A.h]"]
U = outputs["Voltage [V]"]
ocp_fit_data = pd.DataFrame({"Capacity [A.h]": q, "Voltage [V]": U})
ocp_fit_data.head()
Capacity [A.h] Voltage [V]
0 0.047433 0.570425
1 0.056403 0.556259
2 0.066176 0.542092
3 0.076817 0.527926
4 0.088392 0.513760

Fit OCP as a function of stoichiometry

Now, we directly fit a function \(U(x)\) to the pseudo-OCP data.

First, we define the function and initial guesses for the parameters.

def U_half_cell(theta):
    u00 = pybamm.Parameter("u00_pos")
    u10 = pybamm.Parameter("u10_pos")
    u11 = pybamm.Parameter("u11_pos")
    u20 = pybamm.Parameter("u20_pos")
    u21 = pybamm.Parameter("u21_pos")
    u22 = pybamm.Parameter("u22_pos")
    u30 = pybamm.Parameter("u30_pos")
    u31 = pybamm.Parameter("u31_pos")
    u32 = pybamm.Parameter("u32_pos")
    u40 = pybamm.Parameter("u40_pos")
    u41 = pybamm.Parameter("u41_pos")
    u42 = pybamm.Parameter("u42_pos")

    u_eq = (
        u00
        + u10 * pybamm.exp(-u11 * theta)
        + u20 * pybamm.tanh(u21 * (theta - u22))
        + u30 * pybamm.tanh(u31 * (theta - u32))
        + u40 * pybamm.tanh(u41 * (theta - u42))
    )

    return u_eq


ocp_param_init = {
    "u00_pos": 0.2,
    "u10_pos": 2,
    "u11_pos": 30,
    "u20_pos": -0.1,
    "u21_pos": 30,
    "u22_pos": 0.1,
    "u30_pos": -0.1,
    "u31_pos": 30,
    "u32_pos": 0.3,
    "u40_pos": -0.1,
    "u41_pos": 30,
    "u42_pos": 0.6,
}

Then we set up our DataFit object and fit the data.

# Set up Parameter objects to fit
ocp_params = {k: iwp.Parameter(k, initial_value=v) for k, v in ocp_param_init.items()}
# Add the functional form of the OCP
ocp_params = {"Positive electrode OCP [V]": U_half_cell, **ocp_params}

# Use the experimental capacity to map between capacity in the experiment and the
# stoichiometry. In practice we would calculate the capacity from other means,
# (e.g. electrode loading) or use the MSMR model to fit the electrode capacity.
known_parameter_values = {"Positive electrode capacity [A.h]": Q_max_data}

# Set up objective and fit
objective = iwp.objectives.OCPHalfCell(
    "positive",
    ocp_data,
)
ocp = iwp.DataFit(objective, parameters=ocp_params)

# Fit
params_fit_ocp = ocp.run(known_parameter_values)

# Plot
_ = ocp.plot_fit_results()
../../../_images/80e49fabaf341753da55eac5a5703b72adf21557fb06a196e07073b6ba1346ef.png

Then, we look at the fitted parameters.

params_fit_ocp
Result(
  Positive electrode OCP [V]: <function U_half_cell at 0x7b9c50090040>
  u00_pos: 0.267661
  u10_pos: 0.148275
  u11_pos: 21.9393
  u20_pos: -0.115909
  u21_pos: 17.9195
  u22_pos: 0.0648079
  u30_pos: -0.0381462
  u31_pos: 17.4315
  u32_pos: 0.24671
  u40_pos: -0.0194791
  u41_pos: 32.1576
  u42_pos: 0.593834
)