From 77a3a3e045966b2e2cf9184a2a07e69788768ff2 Mon Sep 17 00:00:00 2001 From: Valentin Sulzer Date: Thu, 9 Apr 2020 15:54:05 -0400 Subject: [PATCH 1/4] #939 get simulation working for non-battery model --- pybamm/models/base_model.py | 20 ++++++ pybamm/parameters/parameter_values.py | 7 ++ pybamm/simulation.py | 99 +++++++++++++++++---------- tests/unit/test_simulation.py | 25 +++++-- 4 files changed, 110 insertions(+), 41 deletions(-) diff --git a/pybamm/models/base_model.py b/pybamm/models/base_model.py index 3e6fdd9b7d..516b937c89 100644 --- a/pybamm/models/base_model.py +++ b/pybamm/models/base_model.py @@ -643,6 +643,26 @@ def info(self, symbol_name): print(div) + @property + def default_parameter_values(self): + return pybamm.ParameterValues({}) + + @property + def default_var_pts(self): + return {} + + @property + def default_geometry(self): + return {} + + @property + def default_submesh_types(self): + return {} + + @property + def default_spatial_methods(self): + return {} + @property def default_solver(self): "Return default solver based on whether model is ODE model or DAE model" diff --git a/pybamm/parameters/parameter_values.py b/pybamm/parameters/parameter_values.py index ec939e2e93..dce54dfa91 100644 --- a/pybamm/parameters/parameter_values.py +++ b/pybamm/parameters/parameter_values.py @@ -86,6 +86,13 @@ def __init__(self, values=None, chemistry=None): def __getitem__(self, key): return self._dict_items[key] + def get(self, key, default=None): + "Return item correspoonding to key if it exists, otherwise return default" + try: + return self._dict_items[key] + except KeyError: + return default + def __setitem__(self, key, value): "Call the update functionality when doing a setitem" self.update({key: value}) diff --git a/pybamm/simulation.py b/pybamm/simulation.py index c52eeabf54..6e4c69394b 100644 --- a/pybamm/simulation.py +++ b/pybamm/simulation.py @@ -84,7 +84,7 @@ def __init__( quick_plot_vars=None, C_rate=None, ): - self._parameter_values = parameter_values or model.default_parameter_values + self.parameter_values = parameter_values or model.default_parameter_values if experiment is None: self.operating_mode = "without experiment" @@ -96,11 +96,11 @@ def __init__( self.set_up_experiment(model, experiment) self.geometry = geometry or self.model.default_geometry - self._submesh_types = submesh_types or self.model.default_submesh_types - self._var_pts = var_pts or self.model.default_var_pts - self._spatial_methods = spatial_methods or self.model.default_spatial_methods - self._solver = solver or self.model.default_solver - self._quick_plot_vars = quick_plot_vars + self.submesh_types = submesh_types or self.model.default_submesh_types + self.var_pts = var_pts or self.model.default_var_pts + self.spatial_methods = spatial_methods or self.model.default_spatial_methods + self.solver = solver or self.model.default_solver + self.quick_plot_vars = quick_plot_vars self.reset(update_model=False) @@ -237,12 +237,12 @@ def set_defaults(self): supplied model. """ self.geometry = self._model.default_geometry - self._parameter_values = self._model.default_parameter_values - self._submesh_types = self._model.default_submesh_types - self._var_pts = self._model.default_var_pts - self._spatial_methods = self._model.default_spatial_methods - self._solver = self._model.default_solver - self._quick_plot_vars = None + self.parameter_values = self._model.default_parameter_values + self.submesh_types = self._model.default_submesh_types + self.var_pts = self._model.default_var_pts + self.spatial_methods = self._model.default_spatial_methods + self.solver = self._model.default_solver + self.quick_plot_vars = None def reset(self, update_model=True): """ @@ -267,10 +267,13 @@ def set_parameters(self): if self.model_with_set_params: return None - self._model_with_set_params = self._parameter_values.process_model( - self._model, inplace=True - ) - self._parameter_values.process_geometry(self._geometry) + if self._parameter_values._dict_items == {1: 1}: + self._model_with_set_params = self._model + else: + self._model_with_set_params = self._parameter_values.process_model( + self._model, inplace=True + ) + self._parameter_values.process_geometry(self._geometry) def build(self, check_model=True): """ @@ -340,7 +343,9 @@ def solve( # on t_eval (if provided) to ensure the returned solution captures the # input. If the current is provided as data then the "Current function [A]" # is the tuple (filename, data). - if isinstance(self._parameter_values["Current function [A]"], tuple): + # First, read the current function (if provided, otherwise return None) + current_function = self._parameter_values.get("Current function [A]") + if isinstance(current_function, tuple): filename = self._parameter_values["Current function [A]"][0] time_data = self._parameter_values["Current function [A]"][1][:, 0] # If no t_eval is provided, we use the times provided in the data. @@ -387,13 +392,17 @@ def solve( # If not using a drive cycle and t_eval is not provided, set t_eval # to correspond to a single discharge elif t_eval is None: - C_rate = self._parameter_values["C-rate"] - if isinstance(C_rate, pybamm.InputParameter): - C_rate = inputs["C-rate"] - try: - t_end = 3600 / C_rate - except TypeError: - t_end = 3600 + # Get C-rate, return None if it doesn't exist + C_rate = self._parameter_values.get("C-rate") + if C_rate is None: + t_end = 1 + else: + if isinstance(C_rate, pybamm.InputParameter): + C_rate = inputs["C-rate"] + try: + t_end = 3600 / C_rate + except TypeError: + t_end = 3600 t_eval = np.linspace(0, t_end, 100) self.t_eval = t_eval @@ -544,9 +553,9 @@ def model(self): @model.setter def model(self, model): - self._model = model + self._model = copy.copy(model) self._model_class = model.__class__ - self._model_options = model.options + self._model_options = model.options.copy() @property def model_with_set_params(self): @@ -566,7 +575,7 @@ def geometry(self): @geometry.setter def geometry(self, geometry): - self._geometry = geometry + self._geometry = copy.copy(geometry) self._unprocessed_geometry = copy.deepcopy(geometry) @property @@ -577,10 +586,18 @@ def unprocessed_geometry(self): def parameter_values(self): return self._parameter_values + @parameter_values.setter + def parameter_values(self, parameter_values): + self._parameter_values = copy.copy(parameter_values) + @property def submesh_types(self): return self._submesh_types + @submesh_types.setter + def submesh_types(self, submesh_types): + self._submesh_types = copy.copy(submesh_types) + @property def mesh(self): return self._mesh @@ -589,17 +606,25 @@ def mesh(self): def var_pts(self): return self._var_pts + @var_pts.setter + def var_pts(self, var_pts): + self._var_pts = copy.copy(var_pts) + @property def spatial_methods(self): return self._spatial_methods + @spatial_methods.setter + def spatial_methods(self, spatial_methods): + self._spatial_methods = copy.copy(spatial_methods) + @property def solver(self): return self._solver @solver.setter def solver(self, solver): - self._solver = solver + self._solver = copy.copy(solver) @property def quick_plot_vars(self): @@ -607,7 +632,7 @@ def quick_plot_vars(self): @quick_plot_vars.setter def quick_plot_vars(self, quick_plot_vars): - self._quick_plot_vars = quick_plot_vars + self._quick_plot_vars = copy.copy(quick_plot_vars) @property def solution(self): @@ -656,27 +681,27 @@ def specs( """ if model_options: - self._model_options = model_options + self._model_options = copy.copy(model_options) if geometry: self.geometry = geometry if parameter_values: - self._parameter_values = parameter_values + self.parameter_values = parameter_values if submesh_types: - self._submesh_types = submesh_types + self.submesh_types = submesh_types if var_pts: - self._var_pts = var_pts + self.var_pts = var_pts if spatial_methods: - self._spatial_methods = spatial_methods + self.spatial_methods = spatial_methods if solver: - self._solver = solver + self.solver = solver if quick_plot_vars: - self._quick_plot_vars = quick_plot_vars + self.quick_plot_vars = quick_plot_vars if C_rate: self.C_rate = C_rate - self._parameter_values.update({"C-rate": self.C_rate}) + self.parameter_values.update({"C-rate": self.C_rate}) if ( model_options diff --git a/tests/unit/test_simulation.py b/tests/unit/test_simulation.py index 3cb4dd2b1a..79a7dac3ae 100644 --- a/tests/unit/test_simulation.py +++ b/tests/unit/test_simulation.py @@ -86,6 +86,23 @@ def test_solve(self): if val.size > 1: self.assertTrue(val.has_symbol_of_classes(pybamm.Matrix)) + def test_solve_non_battery_model(self): + + model = pybamm.BaseModel() + v = pybamm.Variable("v") + model.rhs = {v: -v} + model.initial_conditions = {v: 1} + model.variables = {"v": v} + sim = pybamm.Simulation( + model, solver=pybamm.ScipySolver(rtol=1e-10, atol=1e-10) + ) + + sim.solve() + np.testing.assert_array_equal(sim.solution.t, np.linspace(0, 1, 100)) + np.testing.assert_array_almost_equal( + sim.solution["v"].entries, np.exp(-np.linspace(0, 1, 100)) + ) + def test_reuse_commands(self): sim = pybamm.Simulation(pybamm.lithium_ion.SPM()) @@ -210,7 +227,7 @@ def test_step(self): model = pybamm.lithium_ion.SPM() sim = pybamm.Simulation(model) sim.step(dt) # 1 step stores first two points - tau = model.timescale.evaluate() + tau = sim.model.timescale.evaluate() self.assertEqual(sim.solution.t.size, 2) self.assertEqual(sim.solution.y[0, :].size, 2) self.assertEqual(sim.solution.t[0], 0) @@ -236,7 +253,7 @@ def test_step_with_inputs(self): sim.step( dt, inputs={"Current function [A]": 1} ) # 1 step stores first two points - tau = model.timescale.evaluate() + tau = sim.model.timescale.evaluate() self.assertEqual(sim.solution.t.size, 2) self.assertEqual(sim.solution.y[0, :].size, 2) self.assertEqual(sim.solution.t[0], 0) @@ -371,7 +388,7 @@ def test_drive_cycle_data(self): # check solution is returned at the times in the data sim.solve() - tau = model.timescale.evaluate() + tau = sim.model.timescale.evaluate() np.testing.assert_array_almost_equal(sim.solution.t, time_data / tau) # check warning raised if the largest gap in t_eval is bigger than the @@ -405,7 +422,7 @@ def car_current(t): ) sim.solve() current = sim.solution["Current [A]"] - tau = model.timescale.evaluate() + tau = sim.model.timescale.evaluate() self.assertEqual(current(0), 1) self.assertEqual(current(1500 / tau), -0.5) self.assertEqual(current(3000 / tau), 0.5) From 5a8ef1fd08250079dbcfbe939098d391cfe6e1e1 Mon Sep 17 00:00:00 2001 From: Valentin Sulzer Date: Thu, 9 Apr 2020 17:44:56 -0400 Subject: [PATCH 2/4] #939 remove C-rate, make copies of sim attributes --- CHANGELOG.md | 2 + .../cells/BBOXX_Sulzer2019/parameters.csv | 2 +- .../1C_discharge_from_full/parameters.csv | 1 - .../lithium-ion/cells/Kim2011/parameters.csv | 1 + .../cells/LGM50_Chen2020/parameters.csv | 3 +- .../cells/UMBL_Mohtat2020/parameters.csv | 1 + .../cells/kokam_Ecker2015/parameters.csv | 1 + .../cells/kokam_Marquis2019/parameters.csv | 1 + .../parameters.csv | 1 - .../parameters.csv | 1 - .../parameters.csv | 1 - .../parameters.csv | 1 - .../parameters.csv | 1 - pybamm/parameters/parameter_values.py | 84 ++----------------- pybamm/parameters/print_parameters.py | 6 +- pybamm/simulation.py | 47 +++++++---- pybamm/solvers/base_solver.py | 8 ++ .../test_models/standard_model_tests.py | 5 +- .../test_parameters/test_parameter_values.py | 56 ------------- tests/unit/test_simulation.py | 24 +++--- 20 files changed, 78 insertions(+), 169 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f1e879203..f26c077386 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ ## Bug fixes +- Added default values to base model so that it works with the `Simulation` class - Reformatted thermal submodels ([#938](https://github.com/pybamm-team/PyBaMM/pull/938) - Reformatted electrolyte submodels ([#927](https://github.com/pybamm-team/PyBaMM/pull/927)) @@ -20,6 +21,7 @@ - Removed some inputs like `T_inf`, `R_g` and activation energies to some of the standard function parameters. This is because each of those inputs is specific to a particular function (e.g. the reference temperature at which the function was measured). To change a property such as the activation energy, users should create a new function, specifying the relevant property as a `Parameter` or `InputParameter` ([#942](https://github.com/pybamm-team/PyBaMM/pull/942)) - The thermal option 'xyz-lumped' has been removed. The option 'thermal current collector' has also been removed ([#938](https://github.com/pybamm-team/PyBaMM/pull/938) +- The 'C-rate' parameter has been deprecated. Use 'Current function [A]' instead. The cell capacity can be accessed as 'Cell capacity [A.h]', and used to calculate current from C-rate # [v0.2.1](https://github.com/pybamm-team/PyBaMM/tree/v0.2.1) - 2020-03-31 diff --git a/pybamm/input/parameters/lead-acid/cells/BBOXX_Sulzer2019/parameters.csv b/pybamm/input/parameters/lead-acid/cells/BBOXX_Sulzer2019/parameters.csv index 5a5f2bfb84..fa32bd434f 100644 --- a/pybamm/input/parameters/lead-acid/cells/BBOXX_Sulzer2019/parameters.csv +++ b/pybamm/input/parameters/lead-acid/cells/BBOXX_Sulzer2019/parameters.csv @@ -19,7 +19,7 @@ Positive tab centre z-coordinate [m],0.114,Tab at top, # Electrical,,, Cell capacity [A.h],17,Manufacturer, Typical current [A],1,, - +Current function [A],1,default current function, ,,, # Density,,, Negative current collector density [kg.m-3],11300, same as electrode, diff --git a/pybamm/input/parameters/lead-acid/experiments/1C_discharge_from_full/parameters.csv b/pybamm/input/parameters/lead-acid/experiments/1C_discharge_from_full/parameters.csv index 063e70a78b..154de5565e 100644 --- a/pybamm/input/parameters/lead-acid/experiments/1C_discharge_from_full/parameters.csv +++ b/pybamm/input/parameters/lead-acid/experiments/1C_discharge_from_full/parameters.csv @@ -14,7 +14,6 @@ Number of electrodes connected in parallel to make a cell,8,Manufacturer, Number of cells connected in series to make a battery,6,Manufacturer, Lower voltage cut-off [V],1.73,(just under) 10.5V across 6-cell battery, Upper voltage cut-off [V],2.44,(just over) 14.5V across 6-cell battery, -C-rate,0.1,, ,,, # Initial conditions Initial State of Charge,1,-, diff --git a/pybamm/input/parameters/lithium-ion/cells/Kim2011/parameters.csv b/pybamm/input/parameters/lithium-ion/cells/Kim2011/parameters.csv index 1091bea8a3..343f4559d1 100644 --- a/pybamm/input/parameters/lithium-ion/cells/Kim2011/parameters.csv +++ b/pybamm/input/parameters/lithium-ion/cells/Kim2011/parameters.csv @@ -35,3 +35,4 @@ Positive current collector thermal conductivity [W.m-1.K-1],158.079, 237 * 0.667 # Electrical,,, Cell capacity [A.h],0.43,trial and error, Typical current [A],0.43,0.2857,1C current +Current function [A],0.43,default current function, diff --git a/pybamm/input/parameters/lithium-ion/cells/LGM50_Chen2020/parameters.csv b/pybamm/input/parameters/lithium-ion/cells/LGM50_Chen2020/parameters.csv index 8628c2923d..3843429008 100644 --- a/pybamm/input/parameters/lithium-ion/cells/LGM50_Chen2020/parameters.csv +++ b/pybamm/input/parameters/lithium-ion/cells/LGM50_Chen2020/parameters.csv @@ -34,4 +34,5 @@ Positive current collector thermal conductivity [W.m-1.K-1],237,CRC Handbook,alu ,,, # Electrical,,, Cell capacity [A.h],5,Chen 2020, -Typical current [A],5,Chen 2020, \ No newline at end of file +Typical current [A],5,Chen 2020, +Current function [A],5,default current function, diff --git a/pybamm/input/parameters/lithium-ion/cells/UMBL_Mohtat2020/parameters.csv b/pybamm/input/parameters/lithium-ion/cells/UMBL_Mohtat2020/parameters.csv index b45cd098cc..915ea128cc 100644 --- a/pybamm/input/parameters/lithium-ion/cells/UMBL_Mohtat2020/parameters.csv +++ b/pybamm/input/parameters/lithium-ion/cells/UMBL_Mohtat2020/parameters.csv @@ -35,3 +35,4 @@ Positive current collector thermal conductivity [W.m-1.K-1],237,, # Electrical,,, Cell capacity [A.h],5,Peyman MPM, Typical current [A],5,,1C current +Current function [A],5,default current function, diff --git a/pybamm/input/parameters/lithium-ion/cells/kokam_Ecker2015/parameters.csv b/pybamm/input/parameters/lithium-ion/cells/kokam_Ecker2015/parameters.csv index d6f636959e..4be97ac3af 100644 --- a/pybamm/input/parameters/lithium-ion/cells/kokam_Ecker2015/parameters.csv +++ b/pybamm/input/parameters/lithium-ion/cells/kokam_Ecker2015/parameters.csv @@ -13,3 +13,4 @@ Electrode width [m],8.50E-02,, # Electrical,,, Cell capacity [A.h], 0.15625, 7.5/48 (parameter set for a single layer cell), Typical current [A], 0.15652,, +Current function [A],0.15652,default current function, diff --git a/pybamm/input/parameters/lithium-ion/cells/kokam_Marquis2019/parameters.csv b/pybamm/input/parameters/lithium-ion/cells/kokam_Marquis2019/parameters.csv index eddde7ffb5..e52b28c868 100644 --- a/pybamm/input/parameters/lithium-ion/cells/kokam_Marquis2019/parameters.csv +++ b/pybamm/input/parameters/lithium-ion/cells/kokam_Marquis2019/parameters.csv @@ -35,3 +35,4 @@ Positive current collector thermal conductivity [W.m-1.K-1],237,, # Electrical,,, Cell capacity [A.h],0.680616,,24 Ah/m2 * 0.137m * 0.207m Typical current [A],0.680616,,1C current +Current function [A],0.680616,default current function, diff --git a/pybamm/input/parameters/lithium-ion/experiments/1C_charge_from_empty_Mohtat2020/parameters.csv b/pybamm/input/parameters/lithium-ion/experiments/1C_charge_from_empty_Mohtat2020/parameters.csv index 622587d35f..ae32f40bb8 100644 --- a/pybamm/input/parameters/lithium-ion/experiments/1C_charge_from_empty_Mohtat2020/parameters.csv +++ b/pybamm/input/parameters/lithium-ion/experiments/1C_charge_from_empty_Mohtat2020/parameters.csv @@ -11,7 +11,6 @@ Number of electrodes connected in parallel to make a cell,1,, Number of cells connected in series to make a battery,1,, Lower voltage cut-off [V],2.5,, Upper voltage cut-off [V],4.2,, -C-rate,-1,, ,,, # Initial conditions Initial concentration in negative electrode [mol.m-3],48.8682,Peyman MPM, x0 (0.0017) * Csmax_n diff --git a/pybamm/input/parameters/lithium-ion/experiments/1C_discharge_from_full_Chen2020/parameters.csv b/pybamm/input/parameters/lithium-ion/experiments/1C_discharge_from_full_Chen2020/parameters.csv index a826e8176f..7f59fcfd10 100644 --- a/pybamm/input/parameters/lithium-ion/experiments/1C_discharge_from_full_Chen2020/parameters.csv +++ b/pybamm/input/parameters/lithium-ion/experiments/1C_discharge_from_full_Chen2020/parameters.csv @@ -12,7 +12,6 @@ Number of electrodes connected in parallel to make a cell,1,, Number of cells connected in series to make a battery,1,, Lower voltage cut-off [V],2.5,, Upper voltage cut-off [V],4.4,, -C-rate,1,, ,,, # Initial conditions Initial concentration in negative electrode [mol.m-3],30086,Chen 2020, diff --git a/pybamm/input/parameters/lithium-ion/experiments/1C_discharge_from_full_Ecker2015/parameters.csv b/pybamm/input/parameters/lithium-ion/experiments/1C_discharge_from_full_Ecker2015/parameters.csv index fd2cc7c03e..131c087945 100644 --- a/pybamm/input/parameters/lithium-ion/experiments/1C_discharge_from_full_Ecker2015/parameters.csv +++ b/pybamm/input/parameters/lithium-ion/experiments/1C_discharge_from_full_Ecker2015/parameters.csv @@ -12,7 +12,6 @@ Number of electrodes connected in parallel to make a cell,1,, Number of cells connected in series to make a battery,1,, Lower voltage cut-off [V],2.5,, Upper voltage cut-off [V],4.2,, -C-rate,1,, ,,, # Initial conditions Initial concentration in negative electrode [mol.m-3], 26120.05,, diff --git a/pybamm/input/parameters/lithium-ion/experiments/1C_discharge_from_full_Kim2011/parameters.csv b/pybamm/input/parameters/lithium-ion/experiments/1C_discharge_from_full_Kim2011/parameters.csv index 335b774a1d..e1e4b77c65 100644 --- a/pybamm/input/parameters/lithium-ion/experiments/1C_discharge_from_full_Kim2011/parameters.csv +++ b/pybamm/input/parameters/lithium-ion/experiments/1C_discharge_from_full_Kim2011/parameters.csv @@ -12,7 +12,6 @@ Number of electrodes connected in parallel to make a cell,1,, Number of cells connected in series to make a battery,1,, Lower voltage cut-off [V],2.7,, Upper voltage cut-off [V],4.5,, -C-rate,1,, ,,, # Initial conditions Initial concentration in negative electrode [mol.m-3],18081,0.63*2.84E4, diff --git a/pybamm/input/parameters/lithium-ion/experiments/1C_discharge_from_full_Marquis2019/parameters.csv b/pybamm/input/parameters/lithium-ion/experiments/1C_discharge_from_full_Marquis2019/parameters.csv index 37f1a11a3b..bd463472c5 100644 --- a/pybamm/input/parameters/lithium-ion/experiments/1C_discharge_from_full_Marquis2019/parameters.csv +++ b/pybamm/input/parameters/lithium-ion/experiments/1C_discharge_from_full_Marquis2019/parameters.csv @@ -11,7 +11,6 @@ Number of electrodes connected in parallel to make a cell,1,, Number of cells connected in series to make a battery,1,, Lower voltage cut-off [V],3.105,, Upper voltage cut-off [V],4.7,, -C-rate,1,, ,,, # Initial conditions Initial concentration in negative electrode [mol.m-3],19986.609595075,Scott Moura FastDFN, diff --git a/pybamm/parameters/parameter_values.py b/pybamm/parameters/parameter_values.py index dce54dfa91..ccd52f7fa7 100644 --- a/pybamm/parameters/parameter_values.py +++ b/pybamm/parameters/parameter_values.py @@ -5,7 +5,6 @@ import pandas as pd import os import numbers -import numpy as np from pprint import pformat @@ -115,6 +114,11 @@ def items(self): "Get the items of the dictionary" return self._dict_items.items() + def copy(self): + """Returns a copy of the parameter values. Makes sure to copy the internal + dictionary.""" + return ParameterValues(values=self._dict_items.copy()) + def search(self, key, print_values=True): """ Search dictionary for keys containing 'key'. @@ -284,52 +288,12 @@ def check_and_update_parameter_values(self, values): "'Typical current [A]' cannot be zero. A possible alternative is to " "set 'Current function [A]' to `0` instead." ) - if "C-rate" in values and "Current function [A]" in values: + if "C-rate" in values: raise ValueError( - "Cannot provide both 'C-rate' and 'Current function [A]' simultaneously" + "The 'C-rate' parameter has been deprecated, " + "use 'Current function [A]' instead. The cell capacity can be accessed " + "as 'Cell capacity [A.h]', and used to calculate current from C-rate." ) - # If the capacity of the cell has been provided, make sure "C-rate" and current - # match with the stated capacity - if "Cell capacity [A.h]" in values or "Cell capacity [A.h]" in self._dict_items: - # Capacity from values takes precedence - if "Cell capacity [A.h]" in values: - capacity = values["Cell capacity [A.h]"] - else: - capacity = self._dict_items["Cell capacity [A.h]"] - # Make sure they match if both provided - # Update the other if only one provided - if "C-rate" in values: - # Can't provide C-rate as a function - if callable(values["C-rate"]): - value = CrateToCurrent(values["C-rate"], capacity) - elif isinstance(values["C-rate"], tuple): - data = values["C-rate"][1] - current_data = np.stack([data[:, 0], data[:, 1] * capacity], axis=1) - value = (values["C-rate"][0] + "_to_current", current_data) - elif values["C-rate"] == "[input]": - value = CrateToCurrent(values["C-rate"], capacity, typ="input") - else: - value = values["C-rate"] * capacity - self._dict_items["Current function [A]"] = value - elif "Current function [A]" in values: - if callable(values["Current function [A]"]): - value = CurrentToCrate(values["Current function [A]"], capacity) - elif isinstance(values["Current function [A]"], tuple): - data = values["Current function [A]"][1] - c_rate_data = np.stack([data[:, 0], data[:, 1] / capacity], axis=1) - value = ( - values["Current function [A]"][0] + "_to_Crate", - c_rate_data, - ) - elif values["Current function [A]"] == "[input]": - value = CurrentToCrate( - values["Current function [A]"], capacity, typ="input" - ) - else: - value = values["Current function [A]"] / capacity - self._dict_items["C-rate"] = value - - return values def process_model(self, unprocessed_model, inplace=True): """Assign parameter values to a model. @@ -605,33 +569,3 @@ def evaluate(self, symbol): def _ipython_key_completions_(self): return list(self._dict_items.keys()) - - -class CurrentToCrate: - "Convert a current function to a C-rate function" - - def __init__(self, current, capacity, typ="function"): - self.current = current - self.capacity = capacity - self.type = typ - - def __call__(self, t): - if self.type == "function": - return self.current(t) / self.capacity - elif self.type == "input": - return pybamm.InputParameter("Current function [A]") / self.capacity - - -class CrateToCurrent: - "Convert a C-rate function to a current function" - - def __init__(self, Crate, capacity, typ="function"): - self.Crate = Crate - self.capacity = capacity - self.type = typ - - def __call__(self, t): - if self.type == "function": - return self.Crate(t) * self.capacity - elif self.type == "input": - return pybamm.InputParameter("C-rate") * self.capacity diff --git a/pybamm/parameters/print_parameters.py b/pybamm/parameters/print_parameters.py index d529f37be2..7f51aa0280 100644 --- a/pybamm/parameters/print_parameters.py +++ b/pybamm/parameters/print_parameters.py @@ -61,7 +61,11 @@ def print_parameters(parameters, parameter_values, output_file=None): # Calculate parameters for each C-rate for Crate in [1, 10]: # Update Crate - parameter_values.update({"C-rate": Crate}, check_already_exists=False) + capacity = parameter_values.get("Cell capacity [A.h]") + if capacity is not None: + parameter_values.update( + {"Current function [A]": Crate * capacity}, check_already_exists=False + ) for name, symbol in parameters.items(): if not callable(symbol): proc_symbol = parameter_values.process_symbol(symbol) diff --git a/pybamm/simulation.py b/pybamm/simulation.py index 6e4c69394b..07dd2da307 100644 --- a/pybamm/simulation.py +++ b/pybamm/simulation.py @@ -88,9 +88,14 @@ def __init__( if experiment is None: self.operating_mode = "without experiment" - self.C_rate = C_rate - if self.C_rate: - self._parameter_values.update({"C-rate": self.C_rate}) + if C_rate: + self.C_rate = C_rate + self._parameter_values.update( + { + "Current function [A]": self.C_rate + * self._parameter_values["Cell capacity [A.h]"] + } + ) self.model = model else: self.set_up_experiment(model, experiment) @@ -344,8 +349,8 @@ def solve( # input. If the current is provided as data then the "Current function [A]" # is the tuple (filename, data). # First, read the current function (if provided, otherwise return None) - current_function = self._parameter_values.get("Current function [A]") - if isinstance(current_function, tuple): + current = self._parameter_values.get("Current function [A]") + if isinstance(current, tuple): filename = self._parameter_values["Current function [A]"][0] time_data = self._parameter_values["Current function [A]"][1][:, 0] # If no t_eval is provided, we use the times provided in the data. @@ -392,14 +397,15 @@ def solve( # If not using a drive cycle and t_eval is not provided, set t_eval # to correspond to a single discharge elif t_eval is None: - # Get C-rate, return None if it doesn't exist - C_rate = self._parameter_values.get("C-rate") - if C_rate is None: + if current is None: t_end = 1 else: - if isinstance(C_rate, pybamm.InputParameter): - C_rate = inputs["C-rate"] + # Get C-rate, return None if it doesn't exist + capacity = self.parameter_values["Cell capacity [A.h]"] + if isinstance(current, pybamm.InputParameter): + C_rate = inputs["Current function [A]"] / capacity try: + C_rate = current / capacity t_end = 3600 / C_rate except TypeError: t_end = 3600 @@ -575,7 +581,7 @@ def geometry(self): @geometry.setter def geometry(self, geometry): - self._geometry = copy.copy(geometry) + self._geometry = geometry.copy() self._unprocessed_geometry = copy.deepcopy(geometry) @property @@ -588,7 +594,7 @@ def parameter_values(self): @parameter_values.setter def parameter_values(self, parameter_values): - self._parameter_values = copy.copy(parameter_values) + self._parameter_values = parameter_values.copy() @property def submesh_types(self): @@ -596,7 +602,7 @@ def submesh_types(self): @submesh_types.setter def submesh_types(self, submesh_types): - self._submesh_types = copy.copy(submesh_types) + self._submesh_types = submesh_types.copy() @property def mesh(self): @@ -608,7 +614,7 @@ def var_pts(self): @var_pts.setter def var_pts(self, var_pts): - self._var_pts = copy.copy(var_pts) + self._var_pts = var_pts.copy() @property def spatial_methods(self): @@ -616,7 +622,7 @@ def spatial_methods(self): @spatial_methods.setter def spatial_methods(self, spatial_methods): - self._spatial_methods = copy.copy(spatial_methods) + self._spatial_methods = spatial_methods.copy() @property def solver(self): @@ -624,7 +630,7 @@ def solver(self): @solver.setter def solver(self, solver): - self._solver = copy.copy(solver) + self._solver = solver.copy() @property def quick_plot_vars(self): @@ -681,7 +687,7 @@ def specs( """ if model_options: - self._model_options = copy.copy(model_options) + self._model_options = model_options.copy() if geometry: self.geometry = geometry @@ -701,7 +707,12 @@ def specs( if C_rate: self.C_rate = C_rate - self.parameter_values.update({"C-rate": self.C_rate}) + self._parameter_values.update( + { + "Current function [A]": self.C_rate + * self._parameter_values["Cell capacity [A.h]"] + } + ) if ( model_options diff --git a/pybamm/solvers/base_solver.py b/pybamm/solvers/base_solver.py index e32c141045..454fcb3a5f 100644 --- a/pybamm/solvers/base_solver.py +++ b/pybamm/solvers/base_solver.py @@ -2,6 +2,7 @@ # Base solver class # import casadi +import copy import pybamm import numbers import numpy as np @@ -105,6 +106,13 @@ def max_steps(self): def max_steps(self, max_steps): self._max_steps = max_steps + def copy(self): + "Returns a copy of the solver" + new_solver = copy.copy(self) + # clear models_set_up + new_solver.models_set_up = set() + return new_solver + def set_up(self, model, inputs=None): """Unpack model, perform checks, simplify and calculate jacobian. diff --git a/tests/integration/test_models/standard_model_tests.py b/tests/integration/test_models/standard_model_tests.py index 11ea6afe81..27f4d238f2 100644 --- a/tests/integration/test_models/standard_model_tests.py +++ b/tests/integration/test_models/standard_model_tests.py @@ -70,7 +70,10 @@ def test_solving(self, solver=None, t_eval=None): self.solver.rtol = 1e-8 self.solver.atol = 1e-8 - Crate = abs(self.parameter_values["C-rate"]) + Crate = abs( + self.parameter_values["Current function [A]"] + * self.parameter_values["Cell capacity [A.h]"] + ) # don't allow zero C-rate if Crate == 0: Crate = 1 diff --git a/tests/unit/test_parameters/test_parameter_values.py b/tests/unit/test_parameters/test_parameter_values.py index 23288406e2..34bcd11fb8 100644 --- a/tests/unit/test_parameters/test_parameter_values.py +++ b/tests/unit/test_parameters/test_parameter_values.py @@ -83,62 +83,6 @@ def test_check_and_update_parameter_values(self): bad_values = {"Typical current [A]": 0} with self.assertRaisesRegex(ValueError, "Typical current"): pybamm.ParameterValues(bad_values) - # can't provide both C-rate and current function - bad_values = {"C-rate": 1, "Current function [A]": 5} - with self.assertRaisesRegex(ValueError, "Cannot provide both"): - pybamm.ParameterValues(bad_values) - # if only C-rate and capacity provided, update current - values = {"C-rate": 1, "Cell capacity [A.h]": 10} - param = pybamm.ParameterValues(values) - self.assertEqual(param["Current function [A]"], 10) - # if only current and capacity provided, update C-rate - values = {"Current function [A]": 1, "Cell capacity [A.h]": 10} - param = pybamm.ParameterValues(values) - self.assertEqual(param["C-rate"], 1 / 10) - - # With functions - # if only C-rate and capacity provided, update current - values = {"C-rate": pybamm.sin, "Cell capacity [A.h]": 10} - param = pybamm.ParameterValues(values) - self.assertEqual(param["Current function [A]"](2).evaluate(), 10 * np.sin(2)) - # if only current and capacity provided, update C-rate - values = {"Current function [A]": pybamm.exp, "Cell capacity [A.h]": 10} - param = pybamm.ParameterValues(values) - self.assertEqual(param["C-rate"](5).evaluate(), np.exp(5) / 10) - - # With data - # if only C-rate and capacity provided, update current - x = np.linspace(0, 10)[:, np.newaxis] - linear = np.hstack([x, 2 * x]) - values = {"C-rate": ("linear", linear), "Cell capacity [A.h]": 10} - param = pybamm.ParameterValues(values) - self.assertEqual(param["Current function [A]"][0], "linear_to_current") - np.testing.assert_array_equal( - param["Current function [A]"][1], np.hstack([x, 20 * x]) - ) - # if only current and capacity provided, update C-rate - x = np.linspace(0, 10)[:, np.newaxis] - linear = np.hstack([x, 2 * x]) - values = {"Current function [A]": ("linear", linear), "Cell capacity [A.h]": 10} - param = pybamm.ParameterValues(values) - self.assertEqual(param["C-rate"][0], "linear_to_Crate") - np.testing.assert_array_almost_equal( - param["C-rate"][1], np.hstack([x, 0.2 * x]) - ) - - # With input parameters - # if only C-rate and capacity provided, update current - values = {"C-rate": "[input]", "Cell capacity [A.h]": 10} - param = pybamm.ParameterValues(values) - self.assertEqual( - param["Current function [A]"](2).evaluate(inputs={"C-rate": 1}), 10 - ) - # if only current and capacity provided, update C-rate - values = {"Current function [A]": "[input]", "Cell capacity [A.h]": 10} - param = pybamm.ParameterValues(values) - self.assertEqual( - param["C-rate"](5).evaluate(inputs={"Current function [A]": 5}), 0.5 - ) def test_process_symbol(self): parameter_values = pybamm.ParameterValues({"a": 1, "b": 2, "c": 3}) diff --git a/tests/unit/test_simulation.py b/tests/unit/test_simulation.py index 79a7dac3ae..429bad62ec 100644 --- a/tests/unit/test_simulation.py +++ b/tests/unit/test_simulation.py @@ -163,10 +163,14 @@ def test_specs(self): sim.build() def test_set_crate(self): - sim = pybamm.Simulation(pybamm.lithium_ion.SPM(), C_rate=2) - self.assertEqual(sim.parameter_values["C-rate"], 2) + model = pybamm.lithium_ion.SPM() + current_1C = model.default_parameter_values["Current function [A]"] + sim = pybamm.Simulation(model, C_rate=2) + self.assertEqual(sim.parameter_values["Current function [A]"], 2 * current_1C) + self.assertEqual(sim.C_rate, 2) sim.specs(C_rate=3) - self.assertEqual(sim.parameter_values["C-rate"], 3) + self.assertEqual(sim.parameter_values["Current function [A]"], 3 * current_1C) + self.assertEqual(sim.C_rate, 3) def test_set_defaults(self): sim = pybamm.Simulation(pybamm.lithium_ion.SPM()) @@ -330,13 +334,13 @@ def test_set_defaults2(self): # make simulation with silly options (should this be allowed?) sim = pybamm.Simulation( model, - geometry=1, - parameter_values=1, - submesh_types=1, - var_pts=1, - spatial_methods=1, - solver=1, - quick_plot_vars=1, + geometry={}, + parameter_values={}, + submesh_types={}, + var_pts={}, + spatial_methods={}, + solver={}, + quick_plot_vars=[], ) # reset and check From 35cd79ac673b2bf864e1c9b2f73965043f1d5b8b Mon Sep 17 00:00:00 2001 From: Valentin Sulzer Date: Fri, 10 Apr 2020 10:51:22 -0400 Subject: [PATCH 3/4] #939 examples and changelog --- CHANGELOG.md | 5 +++-- examples/notebooks/compare-ecker-data.ipynb | 20 ++++++++++--------- pybamm/parameters/parameter_values.py | 6 +++--- .../test_parameters/test_parameter_values.py | 7 ++++++- 4 files changed, 23 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a6b84fc7fd..7b65bd4e95 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,7 +13,8 @@ ## Bug fixes -- Added default values to base model so that it works with the `Simulation` class +- Changed simulation attributes to assign copies rather than the objects themselves ([#952](https://github.com/pybamm-team/PyBaMM/pull/952) +- Added default values to base model so that it works with the `Simulation` class ([#952](https://github.com/pybamm-team/PyBaMM/pull/952) - Reformatted thermal submodels ([#938](https://github.com/pybamm-team/PyBaMM/pull/938) - Reformatted electrolyte submodels ([#927](https://github.com/pybamm-team/PyBaMM/pull/927)) - Reformatted convection submodels ([#635](https://github.com/pybamm-team/PyBaMM/pull/635)) @@ -22,7 +23,7 @@ - Removed some inputs like `T_inf`, `R_g` and activation energies to some of the standard function parameters. This is because each of those inputs is specific to a particular function (e.g. the reference temperature at which the function was measured). To change a property such as the activation energy, users should create a new function, specifying the relevant property as a `Parameter` or `InputParameter` ([#942](https://github.com/pybamm-team/PyBaMM/pull/942)) - The thermal option 'xyz-lumped' has been removed. The option 'thermal current collector' has also been removed ([#938](https://github.com/pybamm-team/PyBaMM/pull/938) -- The 'C-rate' parameter has been deprecated. Use 'Current function [A]' instead. The cell capacity can be accessed as 'Cell capacity [A.h]', and used to calculate current from C-rate +- The 'C-rate' parameter has been deprecated. Use 'Current function [A]' instead. The cell capacity can be accessed as 'Cell capacity [A.h]', and used to calculate current from C-rate ([#952](https://github.com/pybamm-team/PyBaMM/pull/952) # [v0.2.1](https://github.com/pybamm-team/PyBaMM/tree/v0.2.1) - 2020-03-31 diff --git a/examples/notebooks/compare-ecker-data.ipynb b/examples/notebooks/compare-ecker-data.ipynb index 23fdc414d3..8ac4b3472e 100644 --- a/examples/notebooks/compare-ecker-data.ipynb +++ b/examples/notebooks/compare-ecker-data.ipynb @@ -63,7 +63,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ @@ -73,7 +73,7 @@ "# pick parameters, keeping C-rate as an input to be changed for each solve\n", "chemistry = pybamm.parameter_sets.Ecker2015\n", "parameter_values = pybamm.ParameterValues(chemistry=chemistry)\n", - "parameter_values.update({\"C-rate\": \"[input]\"})" + "parameter_values.update({\"Current function [A]\": \"[input]\"})" ] }, { @@ -85,7 +85,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ @@ -108,7 +108,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -124,11 +124,12 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "C_rates = [1, 5] # C-rates to solve for\n", + "capacity = parameter_values[\"Cell capacity [A.h]\"]\n", "t_evals = [\n", " np.linspace(0, 3800, 100), \n", " np.linspace(0, 720, 100)\n", @@ -137,7 +138,8 @@ "\n", "# loop over C-rates\n", "for i, C_rate in enumerate(C_rates):\n", - " sim.solve(t_eval=t_evals[i], solver=pybamm.CasadiSolver(mode=\"fast\"),inputs={\"C-rate\": C_rate})\n", + " current = C_rate * capacity\n", + " sim.solve(t_eval=t_evals[i], solver=pybamm.CasadiSolver(mode=\"fast\"),inputs={\"Current function [A]\": current})\n", " solutions[i] = sim.solution" ] }, @@ -150,14 +152,14 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 8, "metadata": { "scrolled": true }, "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "
" ] @@ -235,7 +237,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.9" + "version": "3.7.7" } }, "nbformat": 4, diff --git a/pybamm/parameters/parameter_values.py b/pybamm/parameters/parameter_values.py index ccd52f7fa7..7e7668d654 100644 --- a/pybamm/parameters/parameter_values.py +++ b/pybamm/parameters/parameter_values.py @@ -217,6 +217,8 @@ def update(self, values, check_conflict=False, check_already_exists=True, path=" path : string, optional Path from which to load functions """ + # check parameter values + self.check_parameter_values(values) # update for name, value in values.items(): # check for conflicts @@ -276,12 +278,10 @@ def update(self, values, check_conflict=False, check_already_exists=True, path=" values[name] = float(value) else: self._dict_items[name] = value - # check parameter values - self.check_and_update_parameter_values(values) # reset processed symbols self._processed_symbols = {} - def check_and_update_parameter_values(self, values): + def check_parameter_values(self, values): # Make sure typical current is non-zero if "Typical current [A]" in values and values["Typical current [A]"] == 0: raise ValueError( diff --git a/tests/unit/test_parameters/test_parameter_values.py b/tests/unit/test_parameters/test_parameter_values.py index 34bcd11fb8..39156f62a6 100644 --- a/tests/unit/test_parameters/test_parameter_values.py +++ b/tests/unit/test_parameters/test_parameter_values.py @@ -78,11 +78,16 @@ def test_update(self): with self.assertRaisesRegex(KeyError, "Cannot update parameter"): param.update({"b": 1}) - def test_check_and_update_parameter_values(self): + def test_check_parameter_values(self): # Can't provide a current density of 0, as this will cause a ZeroDivision error bad_values = {"Typical current [A]": 0} with self.assertRaisesRegex(ValueError, "Typical current"): pybamm.ParameterValues(bad_values) + bad_values = {"C-rate": 0} + with self.assertRaisesRegex( + ValueError, "The 'C-rate' parameter has been deprecated" + ): + pybamm.ParameterValues(bad_values) def test_process_symbol(self): parameter_values = pybamm.ParameterValues({"a": 1, "b": 2, "c": 3}) From 885e4d294d91e66ef209ed2c39abedf0d7de4ca3 Mon Sep 17 00:00:00 2001 From: Valentin Sulzer Date: Fri, 10 Apr 2020 14:49:29 -0400 Subject: [PATCH 4/4] #939 add test for current as input --- pybamm/simulation.py | 13 ++++++++----- tests/unit/test_simulation.py | 8 ++++++++ 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/pybamm/simulation.py b/pybamm/simulation.py index 07dd2da307..49c7646d10 100644 --- a/pybamm/simulation.py +++ b/pybamm/simulation.py @@ -272,7 +272,8 @@ def set_parameters(self): if self.model_with_set_params: return None - if self._parameter_values._dict_items == {1: 1}: + if self._parameter_values._dict_items == {}: + # Don't process if parameter values is empty self._model_with_set_params = self._model else: self._model_with_set_params = self._parameter_values.process_model( @@ -404,11 +405,13 @@ def solve( capacity = self.parameter_values["Cell capacity [A.h]"] if isinstance(current, pybamm.InputParameter): C_rate = inputs["Current function [A]"] / capacity - try: - C_rate = current / capacity t_end = 3600 / C_rate - except TypeError: - t_end = 3600 + else: + try: + C_rate = current / capacity + t_end = 3600 / C_rate + except TypeError: + t_end = 3600 t_eval = np.linspace(0, t_end, 100) self.t_eval = t_eval diff --git a/tests/unit/test_simulation.py b/tests/unit/test_simulation.py index 429bad62ec..8a59951fd2 100644 --- a/tests/unit/test_simulation.py +++ b/tests/unit/test_simulation.py @@ -248,6 +248,14 @@ def test_step(self): self.assertEqual(sim.solution.t[0], 2 * dt / tau) self.assertEqual(sim.solution.t[1], 3 * dt / tau) + def test_solve_with_inputs(self): + model = pybamm.lithium_ion.SPM() + param = model.default_parameter_values + param.update({"Current function [A]": "[input]"}) + sim = pybamm.Simulation(model, parameter_values=param) + sim.solve(inputs={"Current function [A]": 1}) + np.testing.assert_array_equal(sim.solution.inputs["Current function [A]"], 1) + def test_step_with_inputs(self): dt = 0.001 model = pybamm.lithium_ion.SPM()