Skip to content

Commit 836e57f

Browse files
committed
#1477 merge in #1100
2 parents b3a3091 + cccefb8 commit 836e57f

27 files changed

+2369
-242
lines changed

CHANGELOG.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -160,12 +160,13 @@ This release adds new operators for more complex models, some basic sensitivity
160160

161161
## Breaking changes
162162

163+
- Changed sensitivity API. Removed `ProcessedSymbolicVariable`, all sensitivity now handled within the solvers and `ProcessedVariable` ()
164+
- Renamed `quick_plot_vars` to `output_variables` in `Simulation` to be consistent with `QuickPlot`. Passing `quick_plot_vars` to `Simulation.plot()` has been deprecated and `output_variables` should be passed instead ([#1099](https://github.com/pybamm-team/PyBaMM/pull/1099))
163165
- The "fast diffusion" particle option has been renamed "uniform profile" ([#1130](https://github.com/pybamm-team/PyBaMM/pull/1130))
164166
- The modules containing standard parameters are now classes so they can take options
165167
(e.g. `standard_parameters_lithium_ion` is now `LithiumIonParameters`) ([#1120](https://github.com/pybamm-team/PyBaMM/pull/1120))
166168
- Renamed `quick_plot_vars` to `output_variables` in `Simulation` to be consistent with `QuickPlot`. Passing `quick_plot_vars` to `Simulation.plot()` has been deprecated and `output_variables` should be passed instead ([#1099](https://github.com/pybamm-team/PyBaMM/pull/1099))
167169

168-
169170
# [v0.2.3](https://github.com/pybamm-team/PyBaMM/tree/v0.2.3) - 2020-07-01
170171

171172
This release enables the use of [Google Colab](https://colab.research.google.com/github/pybamm-team/PyBaMM/blob/main/) for running example notebooks, and adds some small new features and bug fixes.

docs/source/solvers/processed_variable.rst

-3
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,3 @@ Post-Process Variables
33

44
.. autoclass:: pybamm.ProcessedVariable
55
:members:
6-
7-
.. autoclass:: pybamm.ProcessedSymbolicVariable
8-
:members:
+366
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,366 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"metadata": {},
6+
"source": [
7+
"# Sensitivity analysis for the DFN"
8+
]
9+
},
10+
{
11+
"cell_type": "markdown",
12+
"metadata": {},
13+
"source": [
14+
"Example showing how to perform sensitivity analysis for the DFN with PyBaMM"
15+
]
16+
},
17+
{
18+
"cell_type": "code",
19+
"execution_count": 1,
20+
"metadata": {},
21+
"outputs": [
22+
{
23+
"name": "stdout",
24+
"output_type": "stream",
25+
"text": [
26+
"Note: you may need to restart the kernel to use updated packages.\n"
27+
]
28+
}
29+
],
30+
"source": [
31+
"%pip install pybamm -q\n",
32+
"import pybamm\n",
33+
"import numpy as np"
34+
]
35+
},
36+
{
37+
"cell_type": "markdown",
38+
"metadata": {},
39+
"source": [
40+
"Load model"
41+
]
42+
},
43+
{
44+
"cell_type": "code",
45+
"execution_count": 2,
46+
"metadata": {},
47+
"outputs": [],
48+
"source": [
49+
"model = pybamm.lithium_ion.SPMe()"
50+
]
51+
},
52+
{
53+
"cell_type": "markdown",
54+
"metadata": {},
55+
"source": [
56+
"Before performing a sensitivity analysis, we scale the parameters with their reference values. Some parameters are functions of states, but we can evaluate them at appropriate values of the states to obtain a reference value. In this notebook, we choose to study the effect on the voltage of:\n",
57+
"- negative particle diffusivity (via Ds_n)\n",
58+
"- positive particle diffusivity (via Ds_p)\n",
59+
"- electrolyte diffusivity (via D_e)\n",
60+
"- electrolyte conductivity (via kappa_e)\n",
61+
"- negative electrode kinetics (via j0_n)\n",
62+
"- positive electrode kinetics (via j0_p)"
63+
]
64+
},
65+
{
66+
"cell_type": "code",
67+
"execution_count": 3,
68+
"metadata": {},
69+
"outputs": [],
70+
"source": [
71+
"param = model.default_parameter_values\n",
72+
"# Get reference values for evaluating functions\n",
73+
"ce_ref = param[\"Typical electrolyte concentration [mol.m-3]\"]\n",
74+
"csn_ref = param[\"Maximum concentration in negative electrode [mol.m-3]\"]\n",
75+
"csp_ref = param[\"Maximum concentration in positive electrode [mol.m-3]\"]\n",
76+
"T_ref = param[\"Reference temperature [K]\"]\n",
77+
"# Evaluate functions at reference values\n",
78+
"Dsn_ref = param[\"Negative electrode diffusivity [m2.s-1]\"](0.5, T_ref).evaluate()\n",
79+
"Dsp_ref = param[\"Positive electrode diffusivity [m2.s-1]\"](0.5, T_ref).evaluate()\n",
80+
"De_ref = param[\"Electrolyte diffusivity [m2.s-1]\"](ce_ref, T_ref).evaluate()\n",
81+
"kappae_ref = param[\"Electrolyte conductivity [S.m-1]\"](ce_ref, T_ref).evaluate()\n",
82+
"j0n_ref = param.evaluate(param[\"Negative electrode exchange-current density [A.m-2]\"](ce_ref, 0.5 * csn_ref, T_ref))\n",
83+
"j0p_ref = param.evaluate(param[\"Positive electrode exchange-current density [A.m-2]\"](ce_ref, 0.5 * csp_ref, T_ref))"
84+
]
85+
},
86+
{
87+
"cell_type": "code",
88+
"execution_count": 4,
89+
"metadata": {},
90+
"outputs": [],
91+
"source": [
92+
"param[\"Negative electrode diffusivity [m2.s-1]\"] = Dsn_ref * pybamm.InputParameter(\"Dsn\")\n",
93+
"param[\"Positive electrode diffusivity [m2.s-1]\"] = Dsp_ref * pybamm.InputParameter(\"Dsp\")\n",
94+
"# param[\"Electrolyte diffusivity [m2.s-1]\"] = De_ref * pybamm.InputParameter(\"D_e\")\n",
95+
"# param[\"Electrolyte conductivity [S.m-1]\"] = kappae_ref * pybamm.InputParameter(\"kappa_e\")\n",
96+
"# param[\"Negative electrode exchange-current density [A.m-2]\"] = j0n_ref * pybamm.InputParameter(\"j0n\")\n",
97+
"# param[\"Positive electrode exchange-current density [A.m-2]\"] = j0p_ref * pybamm.InputParameter(\"j0p\")"
98+
]
99+
},
100+
{
101+
"cell_type": "markdown",
102+
"metadata": {},
103+
"source": [
104+
"Create simulation, run and read solution"
105+
]
106+
},
107+
{
108+
"cell_type": "code",
109+
"execution_count": 6,
110+
"metadata": {},
111+
"outputs": [],
112+
"source": [
113+
"solver = pybamm.CasadiSolver(mode=\"fast\", sensitivity=\"casadi\")\n",
114+
"sim = pybamm.Simulation(model, parameter_values=param, solver=solver)\n",
115+
"solution = sim.solve(t_eval=np.linspace(0,3600), inputs={\"Dsn\": 1, \"Dsp\": 1})"
116+
]
117+
},
118+
{
119+
"cell_type": "code",
120+
"execution_count": 7,
121+
"metadata": {},
122+
"outputs": [
123+
{
124+
"data": {
125+
"text/plain": [
126+
"0.015949444000000312"
127+
]
128+
},
129+
"execution_count": 7,
130+
"metadata": {},
131+
"output_type": "execute_result"
132+
}
133+
],
134+
"source": [
135+
"solution.solve_time"
136+
]
137+
},
138+
{
139+
"cell_type": "markdown",
140+
"metadata": {},
141+
"source": [
142+
"Since we have not specified the parameter values when solving, the resulting solution contains _symbolic_ variables, such as the voltage"
143+
]
144+
},
145+
{
146+
"cell_type": "code",
147+
"execution_count": 13,
148+
"metadata": {},
149+
"outputs": [
150+
{
151+
"name": "stdout",
152+
"output_type": "stream",
153+
"text": [
154+
"CPU times: user 3.73 s, sys: 194 ms, total: 3.92 s\n",
155+
"Wall time: 3.91 s\n"
156+
]
157+
},
158+
{
159+
"data": {
160+
"text/plain": [
161+
"{'all': DM(sparse: 1500-by-100, 73500 nnz\n",
162+
" (30, 0) -> -8.80308e-05\n",
163+
" (31, 0) -> -9.35556e-05\n",
164+
" (32, 0) -> -0.000107887\n",
165+
" ...\n",
166+
" (1497, 98) -> 0.0170617\n",
167+
" (1498, 98) -> 0.021474\n",
168+
" (1499, 98) -> 0.0260439),\n",
169+
" 'Dsn': DM([00, 00, 00, ..., 0.0170617, 0.021474, 0.0260439]),\n",
170+
" 'Dsp': DM([00, 00, 00, ..., 00, 00, 00])}"
171+
]
172+
},
173+
"execution_count": 13,
174+
"metadata": {},
175+
"output_type": "execute_result"
176+
}
177+
],
178+
"source": [
179+
"%%time\n",
180+
"solution[\"X-averaged negative particle concentration\"].sensitivity"
181+
]
182+
},
183+
{
184+
"cell_type": "code",
185+
"execution_count": 17,
186+
"metadata": {},
187+
"outputs": [],
188+
"source": [
189+
"solver = pybamm.CasadiSolver(mode=\"fast\")\n",
190+
"sim = pybamm.Simulation(model, parameter_values=param, solver=solver)\n",
191+
"solution = sim.solve(t_eval=np.linspace(0,3600), inputs={\"Dsn\": 1, \"Dsp\": 1})"
192+
]
193+
},
194+
{
195+
"cell_type": "code",
196+
"execution_count": 18,
197+
"metadata": {},
198+
"outputs": [
199+
{
200+
"data": {
201+
"text/plain": [
202+
"0.005656635999997661"
203+
]
204+
},
205+
"execution_count": 18,
206+
"metadata": {},
207+
"output_type": "execute_result"
208+
}
209+
],
210+
"source": [
211+
"solution.solve_time"
212+
]
213+
},
214+
{
215+
"cell_type": "code",
216+
"execution_count": 11,
217+
"metadata": {},
218+
"outputs": [
219+
{
220+
"data": {
221+
"text/plain": [
222+
"<pybamm.solvers.processed_variable.ProcessedVariable at 0x13da41210>"
223+
]
224+
},
225+
"execution_count": 11,
226+
"metadata": {},
227+
"output_type": "execute_result"
228+
}
229+
],
230+
"source": [
231+
"V = solution[\"Terminal voltage [V]\"]\n",
232+
"V"
233+
]
234+
},
235+
{
236+
"cell_type": "markdown",
237+
"metadata": {},
238+
"source": [
239+
"Now we can evaluate the voltage at specific values for the input parameters to get both the value"
240+
]
241+
},
242+
{
243+
"cell_type": "code",
244+
"execution_count": 12,
245+
"metadata": {},
246+
"outputs": [
247+
{
248+
"data": {
249+
"text/plain": [
250+
"{'all': DM([0, 0.000305216, 0.000323451, 0.000307878, 0.000281315, 0.000252542, 0.000226269, 0.00020523, 0.000191031, 0.000184763, 0.000187613, 0.000201625, 0.000230913, 0.000283916, 0.000377805, 0.000547086, 0.000859691, 0.00144399, 0.00252183, 0.00440237, 0.00728527, 0.0106768, 0.0129031, 0.0123404, 0.00953625, 0.00642767, 0.00416935, 0.00284452, 0.00214823, 0.00179002, 0.00157891, 0.00140318, 0.00120162, 0.000947612, 0.000645371, 0.0003332, 8.76979e-05, 2.15342e-05, 0.000267893, 0.000949333, 0.00213811, 0.00382395, 0.00590563, 0.00821168, 0.0105401, 0.0127, 0.0145411, 0.0159704, 0.0169657, 0.017614]),\n",
251+
" 'Dsn': DM([0, 0.000305216, 0.000323451, 0.000307878, 0.000281315, 0.000252542, 0.000226269, 0.00020523, 0.000191031, 0.000184763, 0.000187613, 0.000201625, 0.000230913, 0.000283916, 0.000377805, 0.000547086, 0.000859691, 0.00144399, 0.00252183, 0.00440237, 0.00728527, 0.0106768, 0.0129031, 0.0123404, 0.00953625, 0.00642767, 0.00416935, 0.00284452, 0.00214823, 0.00179002, 0.00157891, 0.00140318, 0.00120162, 0.000947612, 0.000645371, 0.0003332, 8.76979e-05, 2.15342e-05, 0.000267893, 0.000949333, 0.00213811, 0.00382395, 0.00590563, 0.00821168, 0.0105401, 0.0127, 0.0145411, 0.0159704, 0.0169657, 0.017614])}"
252+
]
253+
},
254+
"execution_count": 12,
255+
"metadata": {},
256+
"output_type": "execute_result"
257+
}
258+
],
259+
"source": [
260+
"V.sensitivity"
261+
]
262+
},
263+
{
264+
"cell_type": "code",
265+
"execution_count": null,
266+
"metadata": {},
267+
"outputs": [],
268+
"source": [
269+
"%%time\n",
270+
"V.value({\"Dsn\": 1, \"Dsp\": 1, \"D_e\": 1, \"kappa_e\": 1, \"j0n\": 1, \"j0p\": 1})"
271+
]
272+
},
273+
{
274+
"cell_type": "markdown",
275+
"metadata": {},
276+
"source": [
277+
"and sensitivity"
278+
]
279+
},
280+
{
281+
"cell_type": "code",
282+
"execution_count": null,
283+
"metadata": {},
284+
"outputs": [],
285+
"source": [
286+
"%%time\n",
287+
"sens = V.sensitivity({\"Dsn\": 1, \"Dsp\": 1, \"D_e\": 1, \"kappa_e\": 1, \"j0n\": 1, \"j0p\": 1})"
288+
]
289+
},
290+
{
291+
"cell_type": "code",
292+
"execution_count": null,
293+
"metadata": {},
294+
"outputs": [],
295+
"source": [
296+
"sens"
297+
]
298+
},
299+
{
300+
"cell_type": "code",
301+
"execution_count": 13,
302+
"metadata": {},
303+
"outputs": [
304+
{
305+
"ename": "AttributeError",
306+
"evalue": "'ProcessedVariable' object has no attribute 'symbolic_inputs_dict'",
307+
"output_type": "error",
308+
"traceback": [
309+
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
310+
"\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)",
311+
"\u001b[0;32m<ipython-input-13-ef5967a63575>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0minputs\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0mk\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;36m1\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mk\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mV\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msymbolic_inputs_dict\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mkeys\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0mh\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m1e-6\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mk\u001b[0m \u001b[0;32min\u001b[0m \u001b[0minputs\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mkeys\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0mV_down\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mV\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mvalue\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0minputs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0minputs\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mk\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m1\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mh\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
312+
"\u001b[0;31mAttributeError\u001b[0m: 'ProcessedVariable' object has no attribute 'symbolic_inputs_dict'"
313+
]
314+
}
315+
],
316+
"source": [
317+
"inputs = {k: 1 for k in V.symbolic_inputs_dict.keys()}\n",
318+
"h = 1e-6\n",
319+
"for k in inputs.keys():\n",
320+
" V_down = V.value(inputs)\n",
321+
" inputs[k] = 1 + h\n",
322+
" V_up = V.value(inputs)\n",
323+
" sens = (V_up - V_down) / h\n",
324+
" print(sens)\n",
325+
" inputs[k] = 1"
326+
]
327+
},
328+
{
329+
"cell_type": "code",
330+
"execution_count": null,
331+
"metadata": {},
332+
"outputs": [],
333+
"source": [
334+
"inputs"
335+
]
336+
},
337+
{
338+
"cell_type": "code",
339+
"execution_count": null,
340+
"metadata": {},
341+
"outputs": [],
342+
"source": []
343+
}
344+
],
345+
"metadata": {
346+
"kernelspec": {
347+
"display_name": "Python 3",
348+
"language": "python",
349+
"name": "python3"
350+
},
351+
"language_info": {
352+
"codemirror_mode": {
353+
"name": "ipython",
354+
"version": 3
355+
},
356+
"file_extension": ".py",
357+
"mimetype": "text/x-python",
358+
"name": "python",
359+
"nbconvert_exporter": "python",
360+
"pygments_lexer": "ipython3",
361+
"version": "3.7.7"
362+
}
363+
},
364+
"nbformat": 4,
365+
"nbformat_minor": 4
366+
}

pybamm/__init__.py

-1
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,6 @@ def version(formatted=False):
209209
#
210210
from .solvers.solution import Solution
211211
from .solvers.processed_variable import ProcessedVariable
212-
from .solvers.processed_symbolic_variable import ProcessedSymbolicVariable
213212
from .solvers.base_solver import BaseSolver
214213
from .solvers.dummy_solver import DummySolver
215214
from .solvers.algebraic_solver import AlgebraicSolver

0 commit comments

Comments
 (0)