Skip to content

Commit 78d1feb

Browse files
Merge pull request #1977 from pybamm-team/simpler-model-copy
simplify model copy
2 parents 142aae0 + bfcb2c6 commit 78d1feb

File tree

12 files changed

+23
-78
lines changed

12 files changed

+23
-78
lines changed

pybamm/discretisations/discretisation.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,8 +182,8 @@ def process_model(self, model, inplace=True, check_model=True):
182182
# since they point to the same object
183183
model_disc = model
184184
else:
185-
# create an empty copy of the original model
186-
model_disc = model.new_empty_copy()
185+
# create a copy of the original model
186+
model_disc = model.new_copy()
187187

188188
# Keep a record of y_slices in the model
189189
model_disc.y_slices = self.y_slices_explicit

pybamm/expression_tree/operations/replace_symbols.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ def process_model(self, unprocessed_model, inplace=True):
5454
# since they point to the same object
5555
model = unprocessed_model
5656
else:
57-
# create a blank model of the same class
58-
model = unprocessed_model.new_empty_copy()
57+
# create a copy of the model
58+
model = unprocessed_model.new_copy()
5959

6060
new_rhs = {}
6161
for variable, equation in unprocessed_model.rhs.items():

pybamm/models/base_model.py

Lines changed: 14 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import warnings
66
from collections import OrderedDict
77

8+
import copy
89
import casadi
910
import numpy as np
1011

@@ -366,35 +367,21 @@ def __getitem__(self, key):
366367
def default_quick_plot_variables(self):
367368
return None
368369

369-
def new_empty_copy(self):
370-
"""
371-
Create an empty copy of the model with the same name and "parameters"
372-
(convert_to_format, etc), but empty equations and variables.
373-
This is usually then called by :class:`pybamm.ParameterValues`,
374-
:class:`pybamm.Discretisation`, or :class:`pybamm.SymbolReplacer`.
375-
"""
376-
new_model = self.__class__(name=self.name)
377-
new_model.use_jacobian = self.use_jacobian
378-
new_model.convert_to_format = self.convert_to_format
379-
new_model._timescale = self.timescale
380-
new_model._length_scales = self.length_scales
381-
382-
# Variables from discretisation
383-
new_model.is_discretised = self.is_discretised
384-
new_model.y_slices = self.y_slices
385-
new_model.concatenated_rhs = self.concatenated_rhs
386-
new_model.concatenated_algebraic = self.concatenated_algebraic
387-
new_model.concatenated_initial_conditions = self.concatenated_initial_conditions
388-
389-
return new_model
390-
391370
def new_copy(self):
392371
"""
393-
Creates an identical copy of the model, using the functionality of
394-
:class:`pybamm.SymbolReplacer` but without performing any replacements
372+
Creates a copy of the model, explicitly copying all the mutable attributes
373+
to avoid issues with shared objects.
395374
"""
396-
replacer = pybamm.SymbolReplacer({})
397-
return replacer.process_model(self, inplace=False)
375+
new_model = copy.copy(self)
376+
new_model._rhs = self.rhs.copy()
377+
new_model._algebraic = self.algebraic.copy()
378+
new_model._initial_conditions = self.initial_conditions.copy()
379+
new_model._boundary_conditions = self.boundary_conditions.copy()
380+
new_model._variables = self.variables.copy()
381+
new_model._events = self.events.copy()
382+
new_model.external_variables = self.external_variables.copy()
383+
new_model._variables_casadi = self._variables_casadi.copy()
384+
return new_model
398385

399386
def update(self, *submodels):
400387
"""
@@ -435,13 +422,7 @@ def set_initial_conditions_from(self, solution, inplace=True):
435422
if inplace is True:
436423
model = self
437424
else:
438-
model = self.new_empty_copy()
439-
model.rhs = self.rhs.copy()
440-
model.algebraic = self.algebraic.copy()
441-
model.initial_conditions = self.initial_conditions.copy()
442-
model.boundary_conditions = self.boundary_conditions.copy()
443-
model.variables = self.variables.copy()
444-
model.events = self.events.copy()
425+
model = self.new_copy()
445426

446427
if isinstance(solution, pybamm.Solution):
447428
solution = solution.last_state

pybamm/models/full_battery_models/base_battery_model.py

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -864,15 +864,6 @@ def build_model(self):
864864
self._built = True
865865
pybamm.logger.info("Finish building {}".format(self.name))
866866

867-
def new_empty_copy(self):
868-
"""See :meth:`pybamm.BaseModel.new_empty_copy()`"""
869-
new_model = self.__class__(name=self.name, options=self.options)
870-
new_model.use_jacobian = self.use_jacobian
871-
new_model.convert_to_format = self.convert_to_format
872-
new_model._timescale = self.timescale
873-
new_model._length_scales = self.length_scales
874-
return new_model
875-
876867
@property
877868
def summary_variables(self):
878869
return self._summary_variables

pybamm/models/full_battery_models/lead_acid/basic_full.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,3 @@ def __init__(self, name="Basic full model"):
294294
pybamm.Event("Maximum voltage", voltage - param.voltage_high_cut),
295295
]
296296
)
297-
298-
def new_empty_copy(self):
299-
return pybamm.BaseModel.new_empty_copy(self)

pybamm/models/full_battery_models/lithium_ion/basic_dfn.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,3 @@ def __init__(self, name="Doyle-Fuller-Newman model"):
286286
pybamm.Event("Minimum voltage", voltage - param.voltage_low_cut),
287287
pybamm.Event("Maximum voltage", voltage - param.voltage_high_cut),
288288
]
289-
290-
def new_empty_copy(self):
291-
return pybamm.BaseModel.new_empty_copy(self)

pybamm/models/full_battery_models/lithium_ion/basic_spm.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,5 +182,3 @@ def __init__(self, name="Single Particle Model"):
182182
pybamm.Event("Maximum voltage", V - param.voltage_high_cut),
183183
]
184184

185-
def new_empty_copy(self):
186-
return pybamm.BaseModel.new_empty_copy(self)

pybamm/models/full_battery_models/lithium_ion/electrode_soh_half_cell.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,3 @@ def __init__(self, working_electrode, name="Electrode-specific SOH model"):
7575
def default_solver(self):
7676
# Use AlgebraicSolver as CasadiAlgebraicSolver gives unnecessary warnings
7777
return pybamm.AlgebraicSolver()
78-
79-
def new_empty_copy(self):
80-
new_model = ElectrodeSOHHalfCell(self.working_electrode, name=self.name)
81-
return new_model

pybamm/parameters/parameter_values.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -422,8 +422,8 @@ def process_model(self, unprocessed_model, inplace=True):
422422
# since they point to the same object
423423
model = unprocessed_model
424424
else:
425-
# create a blank model of the same class
426-
model = unprocessed_model.new_empty_copy()
425+
# create a copy of the model
426+
model = unprocessed_model.new_copy()
427427

428428
if (
429429
len(unprocessed_model.rhs) == 0

pybamm/simulation.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -515,11 +515,11 @@ def build_for_experiment(self, check_model=True):
515515
unbuilt_model,
516516
parameter_values,
517517
) in self.op_conds_to_model_and_param.items():
518-
# It's ok to modify the models in-place as they are not accessible
519-
# from outside the simulation
520518
model_with_set_params = parameter_values.process_model(
521-
unbuilt_model, inplace=True
519+
unbuilt_model, inplace=False
522520
)
521+
# It's ok to modify the model with set parameters in place as it's
522+
# not returned anywhere
523523
built_model = self._disc.process_model(
524524
model_with_set_params, inplace=True, check_model=check_model
525525
)

0 commit comments

Comments
 (0)