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.7.1/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.7.1/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.7.1/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.7.1/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)]

Fit the MSMR model to data¶
We begin by getting literature values for the MSMR parameters from the ionworkspipeline library
lib = iwp.Library()
gr = lib["Graphite - Verbrugge 2017"]
gr_params = gr.parameter_values
This gives us initial guesses for the MSMR species parameters (\(X_j\), \(U^0_j\), and \(w_j\)). We also need estimates for the total electrode capacity and lower excess capacity. We can use the helper function get_initial_capacity_and_lower_excess_capacity
to estimate these from the species parameters and data
gr_params.update(
iwp.data_fits.objectives.get_initial_capacity_and_lower_excess_capacity(
gr_params, "negative", ocp_data
)
)
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, gr_params, "negative", voltage_limits=(0, 1.5)
)
_ = ax[1].set_xlim(0, 50)

Now we can set up the objective and parameters to fit, run the data fit and plot the results.
# Loop over the initial guesses and set up the parameters to fit with appropriate bounds
paramaters_to_fit = {}
for k, v in gr_params.items():
if "X" in k:
bounds = (0, 1)
elif "U0_" in k:
bounds = (max(0, v - 0.5), v + 0.5)
elif "w_" in k:
bounds = (1e-2, 100)
elif "lower excess" in k:
bounds = (0, 0.1 * Q_max_data)
elif "capacity" in k:
bounds = (Q_max_data, 1.5 * Q_max_data)
else:
continue
paramaters_to_fit[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(
"negative", 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=paramaters_to_fit)
# 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)

Lastly, we can look at the fitted parameters.
results
Result(
U0_n_0: 0.0923027
X_n_0: 0.164614
w_n_0: 0.0192288
U0_n_1: 0.132873
X_n_1: 0.127552
w_n_1: 0.0397263
U0_n_2: 0.217203
X_n_2: 0.0420957
w_n_2: 0.191715
U0_n_3: 0.144157
X_n_3: 0.0916031
w_n_3: 0.516452
U0_n_4: 0.0920767
X_n_4: 0.0897261
w_n_4: 0.112263
U0_n_5: 2.58952e-13
X_n_5: 0.484409
w_n_5: 6.88618
Negative electrode capacity [A.h]: 6.93224
Negative electrode lower excess capacity [A.h]: 0.0926413
)
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.03586286, 0.04613266, 0.05718512, 0.06907362, 0.08185415,
0.09558525, 0.10918599, 0.12419556, 0.13897451, 0.15312778,
0.16958582, 0.1874624 , 0.20439283, 0.22257253, 0.24100241,
0.26242384, 0.28174225, 0.30493263, 0.32650766, 0.35039827,
0.37300397, 0.39283282, 0.41468066, 0.43614132, 0.45658043,
0.47633571, 0.49566829, 0.51538415, 0.53440135, 0.55210094,
0.56945601, 0.58738056, 0.60540599, 0.62225325, 0.64313952,
0.66929865, 0.69711475, 0.72619397, 0.74924471, 0.76490469,
0.77775473, 0.78768265, 0.79619104, 0.80497002, 0.81453179,
0.82417389, 0.83827317, 0.85584717, 0.87967041, 0.90688712,
0.9354142 , 0.96073084, 0.98273474, 1.00222191, 1.02006016,
1.03681887, 1.05357109, 1.07040505, 1.08753316, 1.10464276,
1.12216433, 1.13958808, 1.15752197, 1.17667995, 1.1963816 ,
1.21626904, 1.23623279, 1.25576504, 1.27541972, 1.29532532,
1.31498548, 1.33601992, 1.35653162, 1.37809652, 1.40023869,
1.42264359, 1.44557343, 1.46837036, 1.49077318, 1.51064682,
1.530131 , 1.54913398, 1.56538367, 1.58120234, 1.59530676,
1.60747343, 1.61933061, 1.63177789, 1.64437666, 1.65638765,
1.66991415, 1.68309627, 1.7027961 , 1.72177698, 1.74734437,
1.77314531, 1.80489039, 1.82481399, 1.8426782 , 1.85730826,
1.87652489, 1.90025279, 1.92394773, 1.93104564, 1.94497244,
1.95736046, 1.9830968 , 2.01365313, 2.06306822, 2.07969557,
2.09063279, 2.12145786, 2.14100819, 2.16863997, 2.16743835,
2.18664944, 2.19224105, 2.2101525 , 2.2239955 , 2.23617263,
2.25792166, 2.28679835, 2.2837983 , 2.29758734, 2.29869552,
2.33714781, 2.35331894, 2.36868251, 2.39518007, 2.4007118 ,
2.42633776, 2.45271213, 2.46490621, 2.49644449, 2.52281316,
2.55172005, 2.56986657, 2.59099853, 2.6151186 , 2.63333122,
2.64887076, 2.66172978, 2.67593077, 2.69065982, 2.70596999,
2.72514592, 2.74341061, 2.75914281, 2.7788855 , 2.80145843,
2.82236624, 2.84235201, 2.86235559, 2.88156513, 2.90160999,
2.92103685, 2.9399842 , 2.96246205, 3.00300598, 3.03750752,
3.04900458, 3.07071178, 3.08729296, 3.08973145, 3.09516548,
3.10497929, 3.1302618 , 3.14615769, 3.18041646, 3.18725428,
3.20853788, 3.23149092, 3.20853778, 3.22465855, 3.27431101,
3.29611083, 3.31532571, 3.30871937, 3.34066227, 3.34661789,
3.35667342, 3.31919415, 3.37674864, 3.44150072, 3.46272088,
3.43709252, 3.47772894, 3.5058065 , 3.52743589, 3.54441833,
3.54896352, 3.59028037, 3.6697708 , 3.689737 , 3.70568774,
3.70461978, 3.78176272, 3.78066222, 3.77186995, 3.80712448,
3.79498284, 3.79277737, 3.8016033 , 3.79057264, 3.80491534,
3.82148904, 3.8898282 , 3.90294358, 3.91274087, 3.93759333,
3.96000696, 3.99457363, 3.99973229, 3.99560733, 4.032192 ,
4.02114646, 4.05876645, 4.06552526, 4.09105949, 4.12460026,
4.12105799, 4.09105949, 4.14796442, 4.1792011 , 4.17840388,
4.20773549, 4.25600821, 4.2799199 , 4.29694571, 4.31349059,
4.32999549, 4.37185415, 4.38661635, 4.41044229, 4.43688522,
4.4524771 , 4.46951328, 4.48394339, 4.50477678, 4.51912716,
4.53581692, 4.55768844, 4.57510234, 4.59431765, 4.6172272 ,
4.64206109, 4.66807423, 4.69749963, 4.71975481, 4.73730503,
4.75131875, 4.76274267, 4.77230368]),
'Differential voltage [V/Ah]': array([0.38779649, 0.377275 , 0.3673862 , 0.35796436, 0.34861753,
0.33835652, 0.32440145, 0.30032699, 0.25914704, 0.20591876,
0.15803414, 0.12480234, 0.10040782, 0.08348878, 0.07389311,
0.06614814, 0.06097341, 0.0576703 , 0.05561614, 0.05468458,
0.05474589, 0.05580885, 0.05799724, 0.06131688, 0.06609641,
0.07358654, 0.083205 , 0.09626123, 0.11551855, 0.13963528,
0.16567564, 0.18625764, 0.19405857, 0.1896913 , 0.17916887,
0.16637191, 0.15341142, 0.14125442, 0.13028191, 0.12055436,
0.11202511, 0.10459347, 0.09813515, 0.09254222, 0.08769353,
0.08348689, 0.07984744, 0.07667881, 0.07396767, 0.07164987,
0.06965771, 0.06795358, 0.06651135, 0.06530465, 0.0643199 ,
0.06358934, 0.06303938, 0.06267574, 0.06247563, 0.06238775,
0.06228825, 0.06166856, 0.05958608, 0.05352743, 0.04380727,
0.0333971 , 0.02545994, 0.0197849 , 0.01605148, 0.01327893,
0.01140001, 0.01006535, 0.00890052, 0.00806075, 0.00739627,
0.00686305, 0.00641953, 0.00604221, 0.00573659, 0.00547358,
0.00525118, 0.00506891, 0.00491326, 0.00477294, 0.00467545,
0.00457796, 0.00449311, 0.00443209, 0.00439153, 0.00435747,
0.00434036, 0.00433489, 0.0043431 , 0.00436547, 0.00439977,
0.0044502 , 0.00451385, 0.00459687, 0.00469299, 0.00482335,
0.0049563 , 0.00512055, 0.00532261, 0.00555755, 0.00584054,
0.00616432, 0.00656651, 0.00704004, 0.00766392, 0.00839114,
0.00927653, 0.0105797 , 0.01215639, 0.01446957, 0.0178557 ,
0.02260856, 0.03060755, 0.04341501, 0.06055617, 0.07596525,
0.08508375, 0.0912152 , 0.09659501, 0.10227715, 0.10839935,
0.11481459, 0.12109777, 0.12592138, 0.12610396, 0.11762938,
0.10044139, 0.08112398, 0.06463397, 0.05260629, 0.0443469 ,
0.03776502, 0.0325881 , 0.02888522, 0.02576924, 0.02323318,
0.02078248, 0.01825453, 0.01564435, 0.01312656, 0.01105977,
0.00907591, 0.0076892 , 0.00507613, 0.00445002, 0.00401469,
0.00365605, 0.0033685 , 0.00311594, 0.00291036, 0.0026027 ,
0.00245857, 0.00233013, 0.00214144, 0.00206315, 0.00199407,
0.0019325 , 0.00188026, 0.00183284, 0.00178995, 0.00175795,
0.00172595, 0.00169395, 0.00166266, 0.00164077, 0.00161063,
0.00159825, 0.00157727, 0.00157086, 0.00157488, 0.00157889,
0.00158291, 0.0015891 , 0.00160041, 0.00161442, 0.00163161,
0.0016526 , 0.00167529, 0.00170248, 0.00173297, 0.00176915,
0.00180808, 0.00185385, 0.0019058 , 0.00196108, 0.00210181,
0.00218149, 0.00227849, 0.00239093, 0.00251905, 0.00264717,
0.00281274, 0.00322414, 0.00348753, 0.00384681, 0.00420608,
0.00466126, 0.00526506, 0.00602938, 0.00693417, 0.00813053,
0.0096137 , 0.01146969, 0.01356705, 0.01583576, 0.01806371,
0.02016399, 0.02219543, 0.02437527, 0.02695449, 0.03013198,
0.03403245, 0.04005555, 0.04795761, 0.05952959, 0.07750752,
0.10466371]),
'Full voltage [V]': array([0.08008614, 0.08013518, 0.08018422, ..., 0.57032701, 0.57037605,
0.57042509]),
'Full capacity [A.h]': array([4.77230368, 4.77190222, 4.77149802, ..., 0.03593139, 0.03589712,
0.03586286]),
'Full differential capacity [Ah/V]': array([2.34270433e+107, 2.34270433e+107, 2.34270433e+107, 2.34270433e+107,
2.34270433e+107, 2.34270433e+107, 2.34270433e+107, 2.34270433e+107,
2.34270433e+107, 2.34270433e+107, 1.44476680e+106, 1.00500630e+095,
1.03938520e+085, 7.10027607e+074, 1.17189267e+065, 1.92847687e+054,
1.10059960e+045, 3.02555222e+034, 1.33127944e+025, 1.71202716e+015,
1.91860802e+006, 2.40079831e+000, 2.43449648e+000, 2.51859501e+000,
2.59743806e+000, 2.67265908e+000, 2.74575658e+000, 2.82108337e+000,
2.89859393e+000, 2.98659803e+000, 3.11952244e+000, 3.39052850e+000,
3.96682323e+000, 4.92519813e+000, 6.65162145e+000, 9.25961795e+000,
1.20485641e+001, 1.45955428e+001, 1.62023845e+001, 1.70512571e+001,
1.75913843e+001, 1.79092123e+001, 1.81114906e+001, 1.82517903e+001,
1.83252147e+001, 1.83154202e+001, 1.81503716e+001, 1.76979574e+001,
1.66646698e+001, 1.49439113e+001, 1.26393750e+001, 1.03438984e+001,
8.37376340e+000, 6.86846337e+000, 5.86552663e+000, 5.32840410e+000,
5.14971291e+000, 5.23281979e+000, 5.49128389e+000, 5.86030702e+000,
6.31387529e+000, 6.81725393e+000, 7.37327597e+000, 7.99543142e+000,
8.65267910e+000, 9.32255890e+000, 9.99153440e+000, 1.06344759e+001,
1.12629501e+001, 1.18745131e+001, 1.24488421e+001, 1.30258268e+001,
1.35470706e+001, 1.40472531e+001, 1.45064570e+001, 1.49121253e+001,
1.52633929e+001, 1.55466287e+001, 1.57596248e+001, 1.58941179e+001,
1.59775335e+001, 1.60176318e+001, 1.60311245e+001, 1.60532712e+001,
1.61344997e+001, 1.63369462e+001, 1.67935194e+001, 1.77982587e+001,
1.97258637e+001, 2.27330326e+001, 2.76239607e+001, 3.37619107e+001,
4.47590223e+001, 5.65973349e+001, 7.33826084e+001, 9.04798314e+001,
1.10986048e+002, 1.23327630e+002, 1.33960369e+002, 1.42330773e+002,
1.52830377e+002, 1.64974490e+002, 1.76152774e+002, 1.79311066e+002,
1.85248057e+002, 1.90236136e+002, 1.99702835e+002, 2.09344461e+002,
2.21194041e+002, 2.24128053e+002, 2.25766727e+002, 2.29136470e+002,
2.30315490e+002, 2.30710299e+002, 2.30724130e+002, 2.30165206e+002,
2.29867133e+002, 2.28501568e+002, 2.27017633e+002, 2.25403815e+002,
2.21804700e+002, 2.15611627e+002, 2.16329868e+002, 2.12885769e+002,
2.12593145e+002, 2.00990161e+002, 1.95276018e+002, 1.89395435e+002,
1.78233294e+002, 1.75742377e+002, 1.63494114e+002, 1.49703358e+002,
1.42936654e+002, 1.24358895e+002, 1.07743044e+002, 8.86069019e+001,
7.62569870e+001, 6.17776989e+001, 4.56158795e+001, 3.42779421e+001,
2.58347284e+001, 2.02142242e+001, 1.58600084e+001, 1.33037870e+001,
1.19925816e+001, 1.11240685e+001, 1.05179762e+001, 1.00342079e+001,
9.44472935e+000, 8.80485296e+000, 8.28580556e+000, 7.94171131e+000,
7.92949423e+000, 8.54069040e+000, 1.01827691e+001, 1.28146747e+001,
1.61247177e+001, 2.05889352e+001, 2.90738936e+001, 3.62199415e+001,
3.86360673e+001, 4.35570425e+001, 4.80551756e+001, 4.88056809e+001,
5.05836951e+001, 5.42268875e+001, 6.69535736e+001, 7.78882192e+001,
1.08965493e+002, 1.16195432e+002, 1.40295501e+002, 1.68241103e+002,
1.40295381e+002, 1.59764021e+002, 2.23037753e+002, 2.51290084e+002,
2.76027443e+002, 2.67551896e+002, 3.08122532e+002, 3.15551604e+002,
3.27978338e+002, 2.80972643e+002, 3.52302631e+002, 4.25486067e+002,
4.47473526e+002, 4.20787824e+002, 4.62377306e+002, 4.88764830e+002,
5.07722048e+002, 5.21748403e+002, 5.25372522e+002, 5.55755810e+002,
6.00880169e+002, 6.09395233e+002, 6.15373718e+002, 6.14996369e+002,
6.33735116e+002, 6.33589717e+002, 6.32301028e+002, 6.36104831e+002,
6.35205068e+002, 6.34995352e+002, 6.35749146e+002, 6.34771492e+002,
6.35973217e+002, 6.36612302e+002, 6.30760830e+002, 6.28078423e+002,
6.25748043e+002, 6.18587087e+002, 6.10597517e+002, 5.95448773e+002,
5.92895774e+002, 5.94943257e+002, 5.75106303e+002, 5.81492690e+002,
5.58347872e+002, 5.53774221e+002, 5.35370070e+002, 5.08537211e+002,
5.11511252e+002, 5.35370070e+002, 4.88108056e+002, 4.58644178e+002,
4.59425959e+002, 4.29670545e+002, 3.76524141e+002, 3.48475912e+002,
3.27903731e+002, 3.07496754e+002, 2.86796353e+002, 2.33339353e+002,
2.14412258e+002, 1.84198943e+002, 1.51838316e+002, 1.33777691e+002,
1.15333099e+002, 1.01078740e+002, 8.32744943e+001, 7.31912526e+001,
6.37703581e+001, 5.47356940e+001, 4.95041638e+001, 4.48979424e+001,
4.01081653e+001, 3.50723383e+001, 2.96151633e+001, 2.31585353e+001,
1.82092423e+001, 1.44305970e+001, 1.16333816e+001, 9.60649590e+000,
8.15887895e+000]),
'Full differential voltage [V/Ah]': array([4.26857110e-108, 4.26857110e-108, 4.26857110e-108, 4.26857110e-108,
4.26857110e-108, 4.26857110e-108, 4.26857110e-108, 4.26857110e-108,
4.26857110e-108, 4.26857110e-108, 6.92153226e-107, 9.95018636e-096,
9.62107218e-086, 1.40839594e-075, 8.53320468e-066, 5.18543944e-055,
9.08595646e-046, 3.30518175e-035, 7.51157096e-026, 5.84102883e-016,
5.21211207e-007, 4.16528117e-001, 4.10762557e-001, 3.97046765e-001,
3.84994743e-001, 3.74159206e-001, 3.64198344e-001, 3.54473750e-001,
3.44994857e-001, 3.34829124e-001, 3.20561887e-001, 2.94939270e-001,
2.52090890e-001, 2.03037517e-001, 1.50339283e-001, 1.07995816e-001,
8.29974417e-002, 6.85140674e-002, 6.17193106e-002, 5.86467022e-002,
5.68460096e-002, 5.58371851e-002, 5.52135671e-002, 5.47891457e-002,
5.45696200e-002, 5.45988020e-002, 5.50952906e-002, 5.65036959e-002,
6.00071897e-002, 6.69168854e-002, 7.91178360e-002, 9.66753506e-002,
1.19420618e-001, 1.45592973e-001, 1.70487675e-001, 1.87673454e-001,
1.94185582e-001, 1.91101555e-001, 1.82106775e-001, 1.70639524e-001,
1.58381336e-001, 1.46686629e-001, 1.35624925e-001, 1.25071425e-001,
1.15571141e-001, 1.07266686e-001, 1.00084728e-001, 9.40337831e-002,
8.87866848e-002, 8.42139795e-002, 8.03287557e-002, 7.67705587e-002,
7.38166967e-002, 7.11882952e-002, 6.89348197e-002, 6.70595223e-002,
6.55162326e-002, 6.43226272e-002, 6.34532873e-002, 6.29163572e-002,
6.25878833e-002, 6.24312015e-002, 6.23786559e-002, 6.22926001e-002,
6.19789902e-002, 6.12109502e-002, 5.95467797e-002, 5.61852716e-002,
5.06948651e-002, 4.39888517e-002, 3.62004570e-002, 2.96191767e-002,
2.23418642e-002, 1.76686765e-002, 1.36272071e-002, 1.10521868e-002,
9.01014150e-003, 8.10848308e-003, 7.46489435e-003, 7.02588752e-003,
6.54320179e-003, 6.06154321e-003, 5.67689045e-003, 5.57690066e-003,
5.39816727e-003, 5.25662484e-003, 5.00744019e-003, 4.77681613e-003,
4.52091744e-003, 4.46173510e-003, 4.42935065e-003, 4.36421143e-003,
4.34187036e-003, 4.33444022e-003, 4.33418038e-003, 4.34470534e-003,
4.35033919e-003, 4.37633759e-003, 4.40494417e-003, 4.43648214e-003,
4.50847074e-003, 4.63796880e-003, 4.62257020e-003, 4.69735484e-003,
4.70382053e-003, 4.97536792e-003, 5.12095652e-003, 5.27995832e-003,
5.61062402e-003, 5.69014724e-003, 6.11642814e-003, 6.67987689e-003,
6.99610611e-003, 8.04124227e-003, 9.28134164e-003, 1.12858026e-002,
1.31135525e-002, 1.61870710e-002, 2.19221905e-002, 2.91732799e-002,
3.87075871e-002, 4.94701151e-002, 6.30516692e-002, 7.51665672e-002,
8.33848819e-002, 8.98951677e-002, 9.50753249e-002, 9.96590873e-002,
1.05879159e-001, 1.13573731e-001, 1.20688326e-001, 1.25917445e-001,
1.26111448e-001, 1.17086553e-001, 9.82051143e-002, 7.80355351e-002,
6.20165896e-002, 4.85697775e-002, 3.43951179e-002, 2.76091004e-002,
2.58825515e-002, 2.29583999e-002, 2.08094131e-002, 2.04894181e-002,
1.97692161e-002, 1.84410363e-002, 1.49357226e-002, 1.28389121e-002,
9.17721721e-003, 8.60619029e-003, 7.12781231e-003, 5.94385073e-003,
7.12781843e-003, 6.25923153e-003, 4.48354589e-003, 3.97946462e-003,
3.62282818e-003, 3.73759266e-003, 3.24546210e-003, 3.16905377e-003,
3.04898186e-003, 3.55906536e-003, 2.83846873e-003, 2.35025322e-003,
2.23476908e-003, 2.37649462e-003, 2.16273590e-003, 2.04597373e-003,
1.96958159e-003, 1.91663260e-003, 1.90341131e-003, 1.79935141e-003,
1.66422534e-003, 1.64097116e-003, 1.62502878e-003, 1.62602586e-003,
1.57794633e-003, 1.57830844e-003, 1.58152518e-003, 1.57206792e-003,
1.57429475e-003, 1.57481468e-003, 1.57294745e-003, 1.57537005e-003,
1.57239326e-003, 1.57081476e-003, 1.58538697e-003, 1.59215786e-003,
1.59808730e-003, 1.61658725e-003, 1.63774004e-003, 1.67940559e-003,
1.68663709e-003, 1.68083256e-003, 1.73880897e-003, 1.71971207e-003,
1.79099814e-003, 1.80579009e-003, 1.86786684e-003, 1.96642444e-003,
1.95499121e-003, 1.86786684e-003, 2.04872669e-003, 2.18033946e-003,
2.17662929e-003, 2.32736456e-003, 2.65587220e-003, 2.86963881e-003,
3.04967557e-003, 3.25206685e-003, 3.48679469e-003, 4.28560372e-003,
4.66391246e-003, 5.42891280e-003, 6.58595293e-003, 7.47508793e-003,
8.67053783e-003, 9.89327726e-003, 1.20084788e-002, 1.36628349e-002,
1.56812668e-002, 1.82696140e-002, 2.02003210e-002, 2.22727356e-002,
2.49325790e-002, 2.85124987e-002, 3.37664861e-002, 4.31806237e-002,
5.49171670e-002, 6.92972025e-002, 8.59595289e-002, 1.04096229e-001,
1.22565858e-001])}
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.035863 | 0.570425 |
1 | 0.046133 | 0.556259 |
2 | 0.057185 | 0.542092 |
3 | 0.069074 | 0.527926 |
4 | 0.081854 | 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()

Then, we look at the fitted parameters.
params_fit_ocp
Result(
Positive electrode OCP [V]: <function U_half_cell at 0x765ffff98f40>
u00_pos: 0.267649
u10_pos: 0.148293
u11_pos: 21.9377
u20_pos: -0.115897
u21_pos: 17.9204
u22_pos: 0.0648094
u30_pos: -0.0381475
u31_pos: 17.4306
u32_pos: 0.246708
u40_pos: -0.0194796
u41_pos: 32.1567
u42_pos: 0.593834
)