Skip to content

Commit 795a0c0

Browse files
Merge pull request #1974 from pybamm-team/remove-deprecated-experiment-inputs
remove deprecated stuff
2 parents 4f57c57 + fa337e4 commit 795a0c0

File tree

6 files changed

+24
-201
lines changed

6 files changed

+24
-201
lines changed

pybamm/experiments/experiment.py

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
#
44

55
import numpy as np
6-
import warnings
76

87
examples = """
98
@@ -43,17 +42,11 @@ class Experiment:
4342
----------
4443
operating_conditions : list
4544
List of operating conditions
46-
parameters : dict
47-
Dictionary of parameters to use for this experiment, replacing default
48-
parameters as appropriate
4945
period : string, optional
5046
Period (1/frequency) at which to record outputs. Default is 1 minute. Can be
5147
overwritten by individual operating conditions.
5248
termination : list, optional
5349
List of conditions under which to terminate the experiment. Default is None.
54-
use_simulation_setup_type : str
55-
Whether to use the "new" (default) or "old" simulation set-up type. "new" is
56-
faster at simulating individual steps but has higher set-up overhead
5750
drive_cycles : dict
5851
Dictionary of drive cycles to use for this experiment.
5952
cccv_handling : str, optional
@@ -66,32 +59,14 @@ class Experiment:
6659
def __init__(
6760
self,
6861
operating_conditions,
69-
parameters=None,
7062
period="1 minute",
7163
termination=None,
72-
use_simulation_setup_type="new",
7364
drive_cycles={},
7465
cccv_handling="two-step",
7566
):
7667
if cccv_handling not in ["two-step", "ode"]:
7768
raise ValueError("cccv_handling should be either 'two-step' or 'ode'")
7869
self.cccv_handling = cccv_handling
79-
# Deprecations
80-
if parameters is not None:
81-
warnings.simplefilter("always", DeprecationWarning)
82-
warnings.warn(
83-
"'parameters' as an input to the Experiment class will soon be "
84-
"deprecated. Please open an issue if you are using this feature.",
85-
DeprecationWarning,
86-
)
87-
if use_simulation_setup_type == "old":
88-
warnings.simplefilter("always", DeprecationWarning)
89-
warnings.warn(
90-
"'old' simulation setup type for the Experiment class will soon be "
91-
"deprecated. Use 'new' instead. Please open an issue if this gives an "
92-
"error or unexpected results.",
93-
DeprecationWarning,
94-
)
9570

9671
self.period = self.convert_time_to_seconds(period.split())
9772
operating_conditions_cycles = []
@@ -147,15 +122,9 @@ def __init__(
147122
self.operating_conditions, self.events = self.read_operating_conditions(
148123
operating_conditions, drive_cycles
149124
)
150-
parameters = parameters or {}
151-
if isinstance(parameters, dict):
152-
self.parameters = parameters
153-
else:
154-
raise TypeError("experimental parameters should be a dictionary")
155125

156126
self.termination_string = termination
157127
self.termination = self.read_termination(termination)
158-
self.use_simulation_setup_type = use_simulation_setup_type
159128

160129
def __str__(self):
161130
return str(self.operating_conditions_strings)

pybamm/simulation.py

Lines changed: 23 additions & 140 deletions
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,6 @@ def is_notebook():
2727
return False # Probably standard Python interpreter
2828

2929

30-
def constant_current_constant_voltage_constant_power(variables):
31-
I = variables["Current [A]"]
32-
V = variables["Battery voltage [V]"]
33-
s_I = pybamm.InputParameter("Current switch")
34-
s_V = pybamm.InputParameter("Voltage switch")
35-
s_P = pybamm.InputParameter("Power switch")
36-
return (
37-
s_I * (I - pybamm.InputParameter("Current input [A]"))
38-
+ s_V * (V - pybamm.InputParameter("Voltage input [V]"))
39-
+ s_P * (V * I - pybamm.InputParameter("Power input [W]"))
40-
)
41-
42-
4330
class Simulation:
4431
"""A Simulation class for easy building and running of PyBaMM simulations.
4532
@@ -86,8 +73,7 @@ def __init__(
8673
if isinstance(model, pybamm.lithium_ion.BasicDFNHalfCell):
8774
if experiment is not None:
8875
raise NotImplementedError(
89-
"BasicDFNHalfCell is not compatible "
90-
"with experiment simulations yet."
76+
"BasicDFNHalfCell is not compatible with experiment simulations."
9177
)
9278

9379
if experiment is None:
@@ -156,8 +142,6 @@ def set_up_experiment(self, model, experiment):
156142

157143
# Save the experiment
158144
self.experiment = experiment
159-
# Update parameter values with experiment parameters
160-
self._parameter_values.update(experiment.parameters)
161145
# Create a new submodel for each set of operating conditions and update
162146
# parameters and events accordingly
163147
self._experiment_inputs = []
@@ -172,7 +156,7 @@ def set_up_experiment(self, model, experiment):
172156
"Voltage input [V]": 0,
173157
"Power input [W]": 0,
174158
}
175-
op_control = op["electric"][1]
159+
op_units = op["electric"][1]
176160
if op["dc_data"] is not None:
177161
# If operating condition includes a drive cycle, define the interpolant
178162
timescale = self._parameter_values.evaluate(model.timescale)
@@ -181,28 +165,28 @@ def set_up_experiment(self, model, experiment):
181165
op["dc_data"][:, 1],
182166
timescale * (pybamm.t - pybamm.InputParameter("start time")),
183167
)
184-
if op_control == "A":
168+
if op_units == "A":
185169
operating_inputs.update(
186170
{
187171
"Current switch": 1,
188172
"Current input [A]": drive_cycle_interpolant,
189173
}
190174
)
191-
if op_control == "V":
175+
if op_units == "V":
192176
operating_inputs.update(
193177
{
194178
"Voltage switch": 1,
195179
"Voltage input [V]": drive_cycle_interpolant,
196180
}
197181
)
198-
if op_control == "W":
182+
if op_units == "W":
199183
operating_inputs.update(
200184
{"Power switch": 1, "Power input [W]": drive_cycle_interpolant}
201185
)
202186
else:
203-
if op_control in ["A", "C"]:
187+
if op_units in ["A", "C"]:
204188
capacity = self._parameter_values["Nominal cell capacity [A.h]"]
205-
if op_control == "A":
189+
if op_units == "A":
206190
I = op["electric"][0]
207191
Crate = I / capacity
208192
else:
@@ -211,7 +195,7 @@ def set_up_experiment(self, model, experiment):
211195
I = Crate * capacity
212196
if len(op["electric"]) == 4:
213197
# Update inputs for CCCV
214-
op_control = "CCCV" # change to CCCV
198+
op_units = "CCCV" # change to CCCV
215199
V = op["electric"][2]
216200
operating_inputs.update(
217201
{
@@ -225,13 +209,13 @@ def set_up_experiment(self, model, experiment):
225209
operating_inputs.update(
226210
{"Current switch": 1, "Current input [A]": I}
227211
)
228-
elif op_control == "V":
212+
elif op_units == "V":
229213
# Update inputs for constant voltage
230214
V = op["electric"][0]
231215
operating_inputs.update(
232216
{"Voltage switch": 1, "Voltage input [V]": V}
233217
)
234-
elif op_control == "W":
218+
elif op_units == "W":
235219
# Update inputs for constant power
236220
P = op["electric"][0]
237221
operating_inputs.update({"Power switch": 1, "Power input [W]": P})
@@ -267,102 +251,21 @@ def set_up_experiment(self, model, experiment):
267251
# Add time to the experiment times
268252
dt = op["time"]
269253
if dt is None:
270-
if op_control in ["A", "C", "CCCV"]:
254+
if op_units in ["A", "C", "CCCV"]:
271255
# Current control: max simulation time: 3 * max simulation time
272256
# based on C-rate
273257
dt = 3 / abs(Crate) * 3600 # seconds
274-
if op_control == "CCCV":
258+
if op_units == "CCCV":
275259
dt *= 5 # 5x longer for CCCV
276260
else:
277261
# max simulation time: 1 day
278262
dt = 24 * 3600 # seconds
279263
self._experiment_times.append(dt)
280264

281265
# Set up model for experiment
282-
if experiment.use_simulation_setup_type == "old":
283-
self.set_up_model_for_experiment_old(model)
284-
elif experiment.use_simulation_setup_type == "new":
285-
self.set_up_model_for_experiment_new(model)
286-
287-
def set_up_model_for_experiment_old(self, model):
288-
"""
289-
Set up self.model to be able to run the experiment (old version).
290-
In this version, a single model is created which can then be called with
291-
different inputs for current-control, voltage-control, or power-control.
266+
self.set_up_model_for_experiment(model)
292267

293-
This reduces set-up time since only one model needs to be processed, but
294-
increases simulation time since the model formulation is inefficient
295-
"""
296-
# Create a new model where the current density is now a variable
297-
# To do so, we replace all instances of the current density in the
298-
# model with a current density variable, which is obtained from the
299-
# FunctionControl submodel
300-
# create the FunctionControl submodel and extract variables
301-
external_circuit_variables = pybamm.external_circuit.FunctionControl(
302-
model.param, None, model.options
303-
).get_fundamental_variables()
304-
305-
# Perform the replacement
306-
symbol_replacement_map = {
307-
model.variables[name]: variable
308-
for name, variable in external_circuit_variables.items()
309-
}
310-
replacer = pybamm.SymbolReplacer(symbol_replacement_map)
311-
new_model = replacer.process_model(model, inplace=False)
312-
313-
# Update the algebraic equation and initial conditions for FunctionControl
314-
# This creates an algebraic equation for the current to allow current, voltage,
315-
# or power control, together with the appropriate guess for the
316-
# initial condition.
317-
# External circuit submodels are always equations on the current
318-
# The external circuit function should fix either the current, or the voltage,
319-
# or a combination (e.g. I*V for power control)
320-
i_cell = new_model.variables["Total current density"]
321-
new_model.initial_conditions[i_cell] = new_model.param.current_with_time
322-
new_model.algebraic[i_cell] = constant_current_constant_voltage_constant_power(
323-
new_model.variables
324-
)
325-
326-
# Remove upper and lower voltage cut-offs that are *not* part of the experiment
327-
new_model.events = [
328-
event
329-
for event in model.events
330-
if event.name not in ["Minimum voltage", "Maximum voltage"]
331-
]
332-
# add current and voltage events to the model
333-
# current events both negative and positive to catch specification
334-
new_model.events.extend(
335-
[
336-
pybamm.Event(
337-
"Current cut-off (positive) [A] [experiment]",
338-
new_model.variables["Current [A]"]
339-
- abs(pybamm.InputParameter("Current cut-off [A]")),
340-
),
341-
pybamm.Event(
342-
"Current cut-off (negative) [A] [experiment]",
343-
new_model.variables["Current [A]"]
344-
+ abs(pybamm.InputParameter("Current cut-off [A]")),
345-
),
346-
pybamm.Event(
347-
"Voltage cut-off [V] [experiment]",
348-
new_model.variables["Battery voltage [V]"]
349-
- pybamm.InputParameter("Voltage cut-off [V]"),
350-
),
351-
]
352-
)
353-
354-
self.model = new_model
355-
356-
operating_conditions = set(
357-
x["electric"] + (x["time"],) + (x["period"],)
358-
for x in self.experiment.operating_conditions
359-
)
360-
self.op_conds_to_model_and_param = {
361-
op_cond[:2]: (new_model, self.parameter_values)
362-
for op_cond in operating_conditions
363-
}
364-
365-
def set_up_model_for_experiment_new(self, model):
268+
def set_up_model_for_experiment(self, model):
366269
"""
367270
Set up self.model to be able to run the experiment (new version).
368271
In this version, a new model is created for each step.
@@ -612,19 +515,16 @@ def build_for_experiment(self, check_model=True):
612515
unbuilt_model,
613516
parameter_values,
614517
) in self.op_conds_to_model_and_param.items():
615-
if unbuilt_model in processed_models:
616-
built_model = processed_models[unbuilt_model]
617-
else:
618-
# It's ok to modify the models in-place as they are not accessible
619-
# from outside the simulation
620-
model_with_set_params = parameter_values.process_model(
621-
unbuilt_model, inplace=True
622-
)
623-
built_model = self._disc.process_model(
624-
model_with_set_params, inplace=True, check_model=check_model
625-
)
626-
processed_models[unbuilt_model] = built_model
518+
# It's ok to modify the models in-place as they are not accessible
519+
# from outside the simulation
520+
model_with_set_params = parameter_values.process_model(
521+
unbuilt_model, inplace=True
522+
)
523+
built_model = self._disc.process_model(
524+
model_with_set_params, inplace=True, check_model=check_model
525+
)
627526

527+
processed_models[unbuilt_model] = built_model
628528
self.op_conds_to_built_models[op_cond] = built_model
629529

630530
def solve(
@@ -1205,23 +1105,6 @@ def output_variables(self, output_variables):
12051105
def solution(self):
12061106
return self._solution
12071107

1208-
def specs(
1209-
self,
1210-
geometry=None,
1211-
parameter_values=None,
1212-
submesh_types=None,
1213-
var_pts=None,
1214-
spatial_methods=None,
1215-
solver=None,
1216-
output_variables=None,
1217-
C_rate=None,
1218-
):
1219-
"Deprecated method for setting specs"
1220-
raise NotImplementedError(
1221-
"The 'specs' method has been deprecated. "
1222-
"Create a new simulation for each different case instead."
1223-
)
1224-
12251108
def save(self, filename):
12261109
"""Save simulation using pickle"""
12271110
if self.model.convert_to_format == "python":

tests/unit/test_experiments/test_experiment.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ def test_read_strings(self):
3838
"Run US06 (V) for 5 minutes",
3939
"Run US06 (W) for 0.5 hours",
4040
],
41-
{"test": "test"},
4241
drive_cycles={"US06": drive_cycle},
4342
period="20 seconds",
4443
)
@@ -135,7 +134,6 @@ def test_read_strings(self):
135134
None,
136135
],
137136
)
138-
self.assertEqual(experiment.parameters, {"test": "test"})
139137
self.assertEqual(experiment.period, 20)
140138

141139
def test_read_strings_cccv_combined(self):
@@ -326,10 +324,6 @@ def test_bad_strings(self):
326324
pybamm.Experiment(["Discharge at 1 B for 2 hours"])
327325
with self.assertRaisesRegex(ValueError, "time units must be"):
328326
pybamm.Experiment(["Discharge at 1 A for 2 years"])
329-
with self.assertRaisesRegex(
330-
TypeError, "experimental parameters should be a dictionary"
331-
):
332-
pybamm.Experiment([], "not a dictionary")
333327

334328
def test_termination(self):
335329
experiment = pybamm.Experiment(["Discharge at 1 C for 20 seconds"])

tests/unit/test_experiments/test_simulation_with_experiment.py

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -176,23 +176,6 @@ def test_run_experiment_drive_cycle(self):
176176
self.assertIn(("drive_cycle", "V"), sim.op_conds_to_model_and_param)
177177
self.assertIn(("drive_cycle", "W"), sim.op_conds_to_model_and_param)
178178

179-
def test_run_experiment_old_setup_type(self):
180-
experiment = pybamm.Experiment(
181-
[
182-
(
183-
"Discharge at C/20 for 1 hour",
184-
"Charge at 1 A until 4.1 V",
185-
"Hold at 4.1 V until C/2",
186-
"Discharge at 2 W for 1 hour",
187-
),
188-
],
189-
use_simulation_setup_type="old",
190-
)
191-
model = pybamm.lithium_ion.SPM()
192-
sim = pybamm.Simulation(model, experiment=experiment)
193-
solution1 = sim.solve(solver=pybamm.CasadiSolver())
194-
self.assertEqual(solution1.termination, "final time")
195-
196179
def test_run_experiment_breaks_early(self):
197180
experiment = pybamm.Experiment(["Discharge at 2 C for 1 hour"])
198181
model = pybamm.lithium_ion.SPM()

0 commit comments

Comments
 (0)