@@ -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-
4330class 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" :
0 commit comments