Tip
An interactive online version of this notebook is available, which can be accessed via
Alternatively, you may download this notebook and run it offline.
Tutorial 6 - Managing simulation outputs#
In the previous tutorials we have interacted with the outputs of the simulation via the default plotting functionality. However, usually we need to access the output data to manipulate it or transfer to another software, which is the topic of this notebook.
We start by building and solving our model as shown in previous notebooks:
[1]:
%pip install "pybamm[plot,cite]" -q # install PyBaMM if it is not installed
import pybamm
model = pybamm.lithium_ion.SPMe()
sim = pybamm.Simulation(model)
sim.solve([0, 3600])
[notice] A new release of pip is available: 23.3.1 -> 24.0
[notice] To update, run: pip install --upgrade pip
Note: you may need to restart the kernel to use updated packages.
An NVIDIA GPU may be present on this machine, but a CUDA-enabled jaxlib is not installed. Falling back to cpu.
[1]:
<pybamm.solvers.solution.Solution at 0x7f5e5b147fd0>
Accessing solution variables#
We can now access the solved variables directly to visualise or create our own plots. We first extract the solution object:
[2]:
solution = sim.solution
Note that the solution object is also returned when calling the solve
method, so this can be streamlined by running
[3]:
solution = sim.solve([0, 3600])
when solving our simulation. Once we have the solution, we can define post-processed variable for the relevant variables:
[4]:
t = solution["Time [s]"]
V = solution["Voltage [V]"]
(for a list of all the available variables see Tutorial 3). These ProcessedVariable
objects contain the datapoints for the corresponding variable, which can be accessed by calling the entries
variable. For example, for voltage, we can call
[5]:
V.entries
[5]:
array([3.77048098, 3.75309871, 3.74569826, 3.74040906, 3.73582978,
3.73155017, 3.72743983, 3.72345507, 3.71958265, 3.71581858,
3.71216287, 3.70861698, 3.7051823 , 3.70185947, 3.69864846,
3.69554865, 3.69255894, 3.6896778 , 3.68690322, 3.68423281,
3.68166383, 3.67919326, 3.67681781, 3.67453394, 3.67233783,
3.6702254 , 3.66819225, 3.66623353, 3.66434383, 3.66251699,
3.66074577, 3.65902141, 3.65733311, 3.65566717, 3.65400602,
3.65232696, 3.6506007 , 3.64879012, 3.64684952, 3.64472566,
3.64236191, 3.63970731, 3.63673126, 3.63344172, 3.62989992,
3.62622171, 3.6225587 , 3.61906361, 3.61585516, 3.61299814,
3.61050386, 3.60834443, 3.606471 , 3.60482876, 3.60336628,
3.60203993, 3.60081505, 3.59966528, 3.59857137, 3.59751973,
3.59650118, 3.59550993, 3.59454272, 3.59359821, 3.59267644,
3.59177838, 3.59090556, 3.59005965, 3.58924208, 3.58845355,
3.58769359, 3.58695999, 3.58624826, 3.58555109, 3.58485777,
3.58415379, 3.5834204 , 3.58263444, 3.58176818, 3.58078926,
3.57966067, 3.57834049, 3.57678113, 3.57492782, 3.57271582,
3.57006555, 3.566875 , 3.56300793, 3.5582764 , 3.55241508,
3.54504405, 3.53561555, 3.52333845, 3.50707266, 3.48518447,
3.45535426, 3.41433385, 3.35766635, 3.27941791, 3.17203869])
which correspond to the data at the times
[6]:
t.entries
[6]:
array([ 0. , 36.36363636, 72.72727273, 109.09090909,
145.45454545, 181.81818182, 218.18181818, 254.54545455,
290.90909091, 327.27272727, 363.63636364, 400. ,
436.36363636, 472.72727273, 509.09090909, 545.45454545,
581.81818182, 618.18181818, 654.54545455, 690.90909091,
727.27272727, 763.63636364, 800. , 836.36363636,
872.72727273, 909.09090909, 945.45454545, 981.81818182,
1018.18181818, 1054.54545455, 1090.90909091, 1127.27272727,
1163.63636364, 1200. , 1236.36363636, 1272.72727273,
1309.09090909, 1345.45454545, 1381.81818182, 1418.18181818,
1454.54545455, 1490.90909091, 1527.27272727, 1563.63636364,
1600. , 1636.36363636, 1672.72727273, 1709.09090909,
1745.45454545, 1781.81818182, 1818.18181818, 1854.54545455,
1890.90909091, 1927.27272727, 1963.63636364, 2000. ,
2036.36363636, 2072.72727273, 2109.09090909, 2145.45454545,
2181.81818182, 2218.18181818, 2254.54545455, 2290.90909091,
2327.27272727, 2363.63636364, 2400. , 2436.36363636,
2472.72727273, 2509.09090909, 2545.45454545, 2581.81818182,
2618.18181818, 2654.54545455, 2690.90909091, 2727.27272727,
2763.63636364, 2800. , 2836.36363636, 2872.72727273,
2909.09090909, 2945.45454545, 2981.81818182, 3018.18181818,
3054.54545455, 3090.90909091, 3127.27272727, 3163.63636364,
3200. , 3236.36363636, 3272.72727273, 3309.09090909,
3345.45454545, 3381.81818182, 3418.18181818, 3454.54545455,
3490.90909091, 3527.27272727, 3563.63636364, 3600. ])
In addition, post-processed variables can be called at any time, which will return the interpolated value from the data above:
[7]:
V([200, 400, 780, 1236]) # times in seconds
[7]:
array([3.729495 , 3.70861698, 3.67812431, 3.65402263])
Saving the simulation and output data#
In some cases simulations might take a long time to run so it is advisable to save in your computer so it can be analysed later without re-running the simulation. You can save the whole simulation doing:
[8]:
sim.save("SPMe.pkl")
If you now check the root directory of your notebooks you will notice that a new file called "SPMe.pkl"
has appeared. We can load the stored simulation doing
[9]:
sim2 = pybamm.load("SPMe.pkl")
which allows the same manipulation as the original simulation would allow
[10]:
sim2.plot()
[10]:
<pybamm.plotting.quick_plot.QuickPlot at 0x7f5e5ac5c910>
Alternatively, we can just save the solution of the simulation in a similar way
[11]:
sol = sim.solution
sol.save("SPMe_sol.pkl")
and load it in a similar way too
[12]:
sol2 = pybamm.load("SPMe_sol.pkl")
sol2.plot()
[12]:
<pybamm.plotting.quick_plot.QuickPlot at 0x7f5e58ebb5d0>
Another option is to just save the data for some variables
[13]:
sol.save_data("sol_data.pkl", ["Current [A]", "Voltage [V]"])
or save it in .csv
or .mat
format
[14]:
sol.save_data("sol_data.csv", ["Current [A]", "Voltage [V]"], to_format="csv")
# matlab needs names without spaces
sol.save_data(
"sol_data.mat",
["Current [A]", "Voltage [V]"],
to_format="matlab",
short_names={"Current [A]": "I", "Voltage [V]": "V"},
)
Note that while exporting .pkl
works for all variables, exporting to .csv
and .mat
only works for 0D variables (i.e. variables the do not depend on space, only on time).
In this notebook we have shown how to extract and store the outputs of PyBaMM’s simulations. Next, in Tutorial 7 we will show how to change the model options.
Before finishing we will remove the data files we saved so that we leave the directory as we found it
[15]:
import os
os.remove("SPMe.pkl")
os.remove("SPMe_sol.pkl")
os.remove("sol_data.pkl")
os.remove("sol_data.csv")
os.remove("sol_data.mat")
References#
The relevant papers for this notebook are:
[16]:
pybamm.print_citations()
[1] Joel A. E. Andersson, Joris Gillis, Greg Horn, James B. Rawlings, and Moritz Diehl. CasADi – A software framework for nonlinear optimization and optimal control. Mathematical Programming Computation, 11(1):1–36, 2019. doi:10.1007/s12532-018-0139-4.
[2] Charles R. Harris, K. Jarrod Millman, Stéfan J. van der Walt, Ralf Gommers, Pauli Virtanen, David Cournapeau, Eric Wieser, Julian Taylor, Sebastian Berg, Nathaniel J. Smith, and others. Array programming with NumPy. Nature, 585(7825):357–362, 2020. doi:10.1038/s41586-020-2649-2.
[3] Scott G. Marquis, Valentin Sulzer, Robert Timms, Colin P. Please, and S. Jon Chapman. An asymptotic derivation of a single particle model with electrolyte. Journal of The Electrochemical Society, 166(15):A3693–A3706, 2019. doi:10.1149/2.0341915jes.
[4] Valentin Sulzer, Scott G. Marquis, Robert Timms, Martin Robinson, and S. Jon Chapman. Python Battery Mathematical Modelling (PyBaMM). Journal of Open Research Software, 9(1):14, 2021. doi:10.5334/jors.309.