diff --git a/CHANGELOG.md b/CHANGELOG.md index 28ae848226..de93a95d00 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ ## Bug fixes +- Allow models that subclass `BaseBatteryModel` to use custom options classes ([#2571](https://github.com/pybamm-team/PyBaMM/pull/2571)) - Fixed bug with `EntryPoints` in Spyder IDE ([#2584](https://github.com/pybamm-team/PyBaMM/pull/2584)) - Fixed electrolyte conservation when options {"surface form": "algebraic"} are used - Fixed "constant concentration" electrolyte model so that "porosity times concentration" is conserved when porosity changes ([#2529](https://github.com/pybamm-team/PyBaMM/pull/2529)) diff --git a/pybamm/geometry/battery_geometry.py b/pybamm/geometry/battery_geometry.py index 4a71011411..75121b1b6c 100644 --- a/pybamm/geometry/battery_geometry.py +++ b/pybamm/geometry/battery_geometry.py @@ -7,7 +7,6 @@ def battery_geometry( include_particles=True, options=None, - current_collector_dimension=0, form_factor="pouch", ): """ @@ -20,9 +19,6 @@ def battery_geometry( options : dict, optional Dictionary of model options. Necessary for "particle-size geometry", relevant for lithium-ion chemistries. - current_collector_dimensions : int, optional - The dimensions of the current collector. Can be 0 (default), 1 or 2. For - a "cylindrical" form factor the current collector dimension must be 0 or 1. form_factor : str, optional The form factor of the cell. Can be "pouch" (default) or "cylindrical". @@ -32,7 +28,9 @@ def battery_geometry( A geometry class for the battery """ - options = pybamm.BatteryModelOptions(options or {}) + if options is None or type(options) == dict: + options = pybamm.BatteryModelOptions(options) + geo = pybamm.geometric_parameters l_n = geo.n.l l_s = geo.s.l @@ -77,6 +75,7 @@ def battery_geometry( } ) # Add current collector domains + current_collector_dimension = options["dimensionality"] if form_factor == "pouch": if current_collector_dimension == 0: geometry["current collector"] = {"z": {"position": 1}} @@ -105,12 +104,6 @@ def battery_geometry( }, }, } - else: - raise pybamm.GeometryError( - "Invalid current collector dimension '{}' (should be 0, 1 or 2)".format( - current_collector_dimension - ) - ) elif form_factor == "cylindrical": if current_collector_dimension == 0: geometry["current collector"] = {"r_macro": {"position": 1}} diff --git a/pybamm/models/full_battery_models/base_battery_model.py b/pybamm/models/full_battery_models/base_battery_model.py index b9d177c8ee..681c173f8d 100644 --- a/pybamm/models/full_battery_models/base_battery_model.py +++ b/pybamm/models/full_battery_models/base_battery_model.py @@ -686,6 +686,19 @@ def __getitem__(self, key): class BaseBatteryModel(pybamm.BaseModel): """ Base model class with some default settings and required variables + + Parameters + ---------- + options : dict-like, optional + A dictionary of options to be passed to the model. If this is a dict (and not + a subtype of dict), it will be processed by :class:`pybamm.BatteryModelOptions` + to ensure that the options are valid. If this is a subtype of dict, it is + assumed that the options have already been processed and are valid. This allows + for the use of custom options classes. The default options are given by + :class:`pybamm.BatteryModelOptions`. + name : str, optional + The name of the model. The default is "Unnamed battery model". + **Extends:** :class:`pybamm.BaseModel` """ @@ -710,10 +723,7 @@ def length_scales(self, value): @property def default_geometry(self): - return pybamm.battery_geometry( - options=self.options, - current_collector_dimension=self.options["dimensionality"], - ) + return pybamm.battery_geometry(options=self.options) @property def default_var_pts(self): @@ -791,7 +801,13 @@ def options(self): @options.setter def options(self, extra_options): - options = BatteryModelOptions(extra_options) + # if extra_options is a dict then process it into a BatteryModelOptions + # this does not catch cases that subclass the dict type + # so other submodels can pass in their own options class if needed + if extra_options is None or type(extra_options) == dict: + options = BatteryModelOptions(extra_options) + else: + options = extra_options # Options that are incompatible with models if isinstance(self, pybamm.lithium_ion.BaseModel): @@ -884,62 +900,6 @@ def set_standard_output_variables(self): {"y": var.y, "y [m]": var.y * L_z, "z": var.z, "z [m]": var.z * L_z} ) - def build_fundamental(self): - # Get the fundamental variables - for submodel_name, submodel in self.submodels.items(): - pybamm.logger.debug( - "Getting fundamental variables for {} submodel ({})".format( - submodel_name, self.name - ) - ) - self.variables.update(submodel.get_fundamental_variables()) - - self._built_fundamental = True - - def build_coupled_variables(self): - # Note: pybamm will try to get the coupled variables for the submodels in the - # order they are set by the user. If this fails for a particular submodel, - # return to it later and try again. If setting coupled variables fails and - # there are no more submodels to try, raise an error. - submodels = list(self.submodels.keys()) - count = 0 - # For this part the FuzzyDict of variables is briefly converted back into a - # normal dictionary for speed with KeyErrors - self._variables = dict(self._variables) - while len(submodels) > 0: - count += 1 - for submodel_name, submodel in self.submodels.items(): - if submodel_name in submodels: - pybamm.logger.debug( - "Getting coupled variables for {} submodel ({})".format( - submodel_name, self.name - ) - ) - try: - self.variables.update( - submodel.get_coupled_variables(self.variables) - ) - submodels.remove(submodel_name) - except KeyError as key: - if len(submodels) == 1 or count == 100: - # no more submodels to try - raise pybamm.ModelError( - "Missing variable for submodel '{}': {}.\n".format( - submodel_name, key - ) - + "Check the selected " - "submodels provide all of the required variables." - ) - else: - # try setting coupled variables on next loop through - pybamm.logger.debug( - "Can't find {}, trying other submodels first".format( - key - ) - ) - # Convert variables back into FuzzyDict - self.variables = pybamm.FuzzyDict(self._variables) - def build_model_equations(self): # Set model equations for submodel_name, submodel in self.submodels.items(): diff --git a/pybamm/models/full_battery_models/equivalent_circuit/thevenin.py b/pybamm/models/full_battery_models/equivalent_circuit/thevenin.py index 0414f3fde3..6de80aafac 100644 --- a/pybamm/models/full_battery_models/equivalent_circuit/thevenin.py +++ b/pybamm/models/full_battery_models/equivalent_circuit/thevenin.py @@ -111,15 +111,7 @@ def set_options(self, extra_options=None): ) ) - self.ecm_options = options - - # Hack to deal with submodels requiring electrochemical model - # options - self.options = pybamm.BatteryModelOptions({}) - self.options["calculate discharge energy"] = self.ecm_options[ - "calculate discharge energy" - ] - self.options["operating mode"] = self.ecm_options["operating mode"] + self.options = options def set_external_circuit_submodel(self): """ @@ -167,34 +159,34 @@ def set_external_circuit_submodel(self): def set_ocv_submodel(self): self.submodels[ "Open circuit voltage" - ] = pybamm.equivalent_circuit_elements.OCVElement(self.param, self.ecm_options) + ] = pybamm.equivalent_circuit_elements.OCVElement(self.param, self.options) def set_resistor_submodel(self): name = "Element-0 (Resistor)" self.submodels[name] = pybamm.equivalent_circuit_elements.ResistorElement( - self.param, self.ecm_options + self.param, self.options ) self.element_counter += 1 def set_rc_submodels(self): - number_of_rc_elements = self.ecm_options["number of rc elements"] + number_of_rc_elements = self.options["number of rc elements"] for _ in range(number_of_rc_elements): name = f"Element-{self.element_counter} (RC)" self.submodels[name] = pybamm.equivalent_circuit_elements.RCElement( - self.param, self.element_counter, self.ecm_options + self.param, self.element_counter, self.options ) self.element_counter += 1 def set_thermal_submodel(self): self.submodels["Thermal"] = pybamm.equivalent_circuit_elements.ThermalSubModel( - self.param, self.ecm_options + self.param, self.options ) def set_voltage_submodel(self): self.submodels["Voltage"] = pybamm.equivalent_circuit_elements.VoltageModel( - self.param, self.ecm_options + self.param, self.options ) def set_submodels(self, build): diff --git a/pybamm/models/full_battery_models/lead_acid/base_lead_acid_model.py b/pybamm/models/full_battery_models/lead_acid/base_lead_acid_model.py index 82164d9a7e..7a43825c19 100644 --- a/pybamm/models/full_battery_models/lead_acid/base_lead_acid_model.py +++ b/pybamm/models/full_battery_models/lead_acid/base_lead_acid_model.py @@ -10,6 +10,22 @@ class BaseModel(pybamm.BaseBatteryModel): Overwrites default parameters from Base Model with default parameters for lead-acid models + Parameters + ---------- + options : dict-like, optional + A dictionary of options to be passed to the model. If this is a dict (and not + a subtype of dict), it will be processed by :class:`pybamm.BatteryModelOptions` + to ensure that the options are valid. If this is a subtype of dict, it is + assumed that the options have already been processed and are valid. This allows + for the use of custom options classes. The default options are given by + :class:`pybamm.BatteryModelOptions`. + name : str, optional + The name of the model. The default is "Unnamed battery model". + build : bool, optional + Whether to build the model on instantiation. Default is True. Setting this + option to False allows users to change any number of the submodels before + building the complete model (submodels cannot be changed after the model is + built). **Extends:** :class:`pybamm.BaseBatteryModel` @@ -17,7 +33,7 @@ class BaseModel(pybamm.BaseBatteryModel): def __init__(self, options=None, name="Unnamed lead-acid model", build=False): options = options or {} - # Specify that there are no particles in lead-acid, and no half-cell models + # Specify that there are no particles in lead-acid options["particle shape"] = "no particles" super().__init__(options, name) self.param = pybamm.LeadAcidParameters() @@ -42,10 +58,7 @@ def default_parameter_values(self): @property def default_geometry(self): - return pybamm.battery_geometry( - include_particles=False, - current_collector_dimension=self.options["dimensionality"], - ) + return pybamm.battery_geometry(include_particles=False, options=self.options) @property def default_var_pts(self): diff --git a/pybamm/models/full_battery_models/lead_acid/full.py b/pybamm/models/full_battery_models/lead_acid/full.py index 7dd00fb986..9709eb3778 100644 --- a/pybamm/models/full_battery_models/lead_acid/full.py +++ b/pybamm/models/full_battery_models/lead_acid/full.py @@ -9,19 +9,8 @@ class Full(BaseModel): """ Porous electrode model for lead-acid, from [1]_, based on the Newman-Tiedemann model. + See :class:`pybamm.lead_acid.BaseModel` for more details. - Parameters - ---------- - options : dict, optional - A dictionary of options to be passed to the model. For a detailed list of - options see :class:`~pybamm.BatteryModelOptions`. - name : str, optional - The name of the model. - build : bool, optional - Whether to build the model on instantiation. Default is True. Setting this - option to False allows users to change any number of the submodels before - building the complete model (submodels cannot be changed after the model is - built). References ---------- diff --git a/pybamm/models/full_battery_models/lead_acid/loqs.py b/pybamm/models/full_battery_models/lead_acid/loqs.py index c4839a23ea..97ab4cc15d 100644 --- a/pybamm/models/full_battery_models/lead_acid/loqs.py +++ b/pybamm/models/full_battery_models/lead_acid/loqs.py @@ -8,19 +8,7 @@ class LOQS(BaseModel): """ Leading-Order Quasi-Static model for lead-acid, from [1]_. - - Parameters - ---------- - options : dict, optional - A dictionary of options to be passed to the model. For a detailed list of - options see :class:`~pybamm.BatteryModelOptions`. - name : str, optional - The name of the model. - build : bool, optional - Whether to build the model on instantiation. Default is True. Setting this - option to False allows users to change any number of the submodels before - building the complete model (submodels cannot be changed after the model is - built). + See :class:`pybamm.lead_acid.BaseModel` for more details. References ---------- diff --git a/pybamm/models/full_battery_models/lithium_ion/base_lithium_ion_model.py b/pybamm/models/full_battery_models/lithium_ion/base_lithium_ion_model.py index 90af6acbcb..017d8bb13a 100644 --- a/pybamm/models/full_battery_models/lithium_ion/base_lithium_ion_model.py +++ b/pybamm/models/full_battery_models/lithium_ion/base_lithium_ion_model.py @@ -9,13 +9,30 @@ class BaseModel(pybamm.BaseBatteryModel): Overwrites default parameters from Base Model with default parameters for lithium-ion models + Parameters + ---------- + options : dict-like, optional + A dictionary of options to be passed to the model. If this is a dict (and not + a subtype of dict), it will be processed by :class:`pybamm.BatteryModelOptions` + to ensure that the options are valid. If this is a subtype of dict, it is + assumed that the options have already been processed and are valid. This allows + for the use of custom options classes. The default options are given by + :class:`pybamm.BatteryModelOptions`. + name : str, optional + The name of the model. The default is "Unnamed battery model". + build : bool, optional + Whether to build the model on instantiation. Default is True. Setting this + option to False allows users to change any number of the submodels before + building the complete model (submodels cannot be changed after the model is + built). + **Extends:** :class:`pybamm.BaseBatteryModel` """ def __init__(self, options=None, name="Unnamed lithium-ion model", build=False): super().__init__(options, name) - self.param = pybamm.LithiumIonParameters(options) + self.param = pybamm.LithiumIonParameters(self.options) # Default timescale self._timescale = self.param.timescale diff --git a/pybamm/models/full_battery_models/lithium_ion/dfn.py b/pybamm/models/full_battery_models/lithium_ion/dfn.py index 83e62fc15f..6f752780a7 100644 --- a/pybamm/models/full_battery_models/lithium_ion/dfn.py +++ b/pybamm/models/full_battery_models/lithium_ion/dfn.py @@ -8,19 +8,8 @@ class DFN(BaseModel): """ Doyle-Fuller-Newman (DFN) model of a lithium-ion battery, from [1]_. + See :class:`pybamm.lithium_ion.BaseModel` for more details. - Parameters - ---------- - options : dict, optional - A dictionary of options to be passed to the model. For a detailed list of - options see :class:`~pybamm.BatteryModelOptions`. - name : str, optional - The name of the model. - build : bool, optional - Whether to build the model on instantiation. Default is True. Setting this - option to False allows users to change any number of the submodels before - building the complete model (submodels cannot be changed after the model is - built). Examples -------- >>> import pybamm diff --git a/pybamm/models/full_battery_models/lithium_ion/mpm.py b/pybamm/models/full_battery_models/lithium_ion/mpm.py index 5a171b3f11..0012ec56e6 100644 --- a/pybamm/models/full_battery_models/lithium_ion/mpm.py +++ b/pybamm/models/full_battery_models/lithium_ion/mpm.py @@ -9,19 +9,8 @@ class MPM(SPM): """ Many-Particle Model (MPM) of a lithium-ion battery with particle-size distributions for each electrode, from [1]_. + See :class:`pybamm.lithium_ion.BaseModel` for more details. - Parameters - ---------- - options : dict, optional - A dictionary of options to be passed to the model. For a detailed list of - options see :class:`~pybamm.BatteryModelOptions`. - name : str, optional - The name of the model. - build : bool, optional - Whether to build the model on instantiation. Default is True. Setting this - option to False allows users to change any number of the submodels before - building the complete model (submodels cannot be changed after the model is - built). Examples -------- >>> import pybamm diff --git a/pybamm/models/full_battery_models/lithium_ion/newman_tobias.py b/pybamm/models/full_battery_models/lithium_ion/newman_tobias.py index 340f0a108b..c0d0384db6 100644 --- a/pybamm/models/full_battery_models/lithium_ion/newman_tobias.py +++ b/pybamm/models/full_battery_models/lithium_ion/newman_tobias.py @@ -15,18 +15,8 @@ class NewmanTobias(DFN): charge as in [2]_. The user can pass the "particle" option to include mass transport in the particles. - Parameters - ---------- - options : dict, optional - A dictionary of options to be passed to the model. For a detailed list of - options see :class:`~pybamm.BatteryModelOptions`. - name : str, optional - The name of the model. - build : bool, optional - Whether to build the model on instantiation. Default is True. Setting this - option to False allows users to change any number of the submodels before - building the complete model (submodels cannot be changed after the model is - built). + See :class:`pybamm.lithium_ion.BaseModel` for more details. + References ---------- diff --git a/pybamm/models/full_battery_models/lithium_ion/spm.py b/pybamm/models/full_battery_models/lithium_ion/spm.py index af16e15f53..cd994be210 100644 --- a/pybamm/models/full_battery_models/lithium_ion/spm.py +++ b/pybamm/models/full_battery_models/lithium_ion/spm.py @@ -8,19 +8,8 @@ class SPM(BaseModel): """ Single Particle Model (SPM) of a lithium-ion battery, from [1]_. + See :class:`pybamm.lithium_ion.BaseModel` for more details. - Parameters - ---------- - options : dict, optional - A dictionary of options to be passed to the model. For a detailed list of - options see :class:`~pybamm.BatteryModelOptions`. - name : str, optional - The name of the model. - build : bool, optional - Whether to build the model on instantiation. Default is True. Setting this - option to False allows users to change any number of the submodels before - building the complete model (submodels cannot be changed after the model is - built). Examples -------- >>> import pybamm diff --git a/pybamm/models/full_battery_models/lithium_ion/spme.py b/pybamm/models/full_battery_models/lithium_ion/spme.py index e9210ac309..07d90f2ede 100644 --- a/pybamm/models/full_battery_models/lithium_ion/spme.py +++ b/pybamm/models/full_battery_models/lithium_ion/spme.py @@ -9,19 +9,8 @@ class SPMe(SPM): """ Single Particle Model with Electrolyte (SPMe) of a lithium-ion battery, from [1]_. Inherits most submodels from SPM, only modifies potentials and electrolyte. + See :class:`pybamm.lithium_ion.BaseModel` for more details. - Parameters - ---------- - options : dict, optional - A dictionary of options to be passed to the model. For a detailed list of - options see :class:`~pybamm.BatteryModelOptions`. - name : str, optional - The name of the model. - build : bool, optional - Whether to build the model on instantiation. Default is True. Setting this - option to False allows users to change any number of the submodels before - building the complete model (submodels cannot be changed after the model is - built). Examples -------- >>> import pybamm diff --git a/pybamm/models/submodels/base_submodel.py b/pybamm/models/submodels/base_submodel.py index a2f450e04b..5f988b6daa 100644 --- a/pybamm/models/submodels/base_submodel.py +++ b/pybamm/models/submodels/base_submodel.py @@ -72,7 +72,11 @@ def __init__( self.name = name self.external = external - self.options = pybamm.BatteryModelOptions(options or {}) + + if options is None or type(options) == dict: + options = pybamm.BatteryModelOptions(options) + + self.options = options self.param = param if param is None or domain is None: diff --git a/pybamm/parameters/base_parameters.py b/pybamm/parameters/base_parameters.py index 75cf12bbec..510acb9ffc 100644 --- a/pybamm/parameters/base_parameters.py +++ b/pybamm/parameters/base_parameters.py @@ -62,7 +62,10 @@ def options(self): @options.setter def options(self, extra_options): - self._options = pybamm.BatteryModelOptions(extra_options) + if extra_options is None or type(extra_options) == dict: + self._options = pybamm.BatteryModelOptions(extra_options) + else: + self._options = extra_options @property def domain(self): diff --git a/tests/shared.py b/tests/shared.py index f8a5b6bc65..dceea22f4a 100644 --- a/tests/shared.py +++ b/tests/shared.py @@ -123,8 +123,8 @@ def get_size_distribution_mesh_for_testing( zpts=15, cc_submesh=pybamm.Uniform1DSubMesh, ): - options = {"particle size": "distribution"} - geometry = pybamm.battery_geometry(options=options, current_collector_dimension=1) + options = {"particle size": "distribution", "dimensionality": 1} + geometry = pybamm.battery_geometry(options=options) return get_mesh_for_testing( xpts=xpts, rpts=rpts, @@ -141,7 +141,7 @@ def get_1p1d_mesh_for_testing( zpts=15, cc_submesh=pybamm.Uniform1DSubMesh, ): - geometry = pybamm.battery_geometry(current_collector_dimension=1) + geometry = pybamm.battery_geometry(options={"dimensionality": 1}) return get_mesh_for_testing( xpts=xpts, rpts=rpts, zpts=zpts, geometry=geometry, cc_submesh=cc_submesh ) @@ -156,7 +156,7 @@ def get_2p1d_mesh_for_testing( cc_submesh=pybamm.MeshGenerator(pybamm.ScikitUniform2DSubMesh), ): geometry = pybamm.battery_geometry( - include_particles=include_particles, current_collector_dimension=2 + include_particles=include_particles, options={"dimensionality": 2} ) return get_mesh_for_testing( xpts=xpts, @@ -186,7 +186,7 @@ def get_unit_2p1D_mesh_for_testing(ypts=15, zpts=15, include_particles=True): ) geometry = pybamm.battery_geometry( - include_particles=include_particles, current_collector_dimension=2 + include_particles=include_particles, options={"dimensionality": 2} ) param.process_geometry(geometry) @@ -207,7 +207,7 @@ def get_cylindrical_mesh_for_testing( ): geometry = pybamm.battery_geometry( include_particles=include_particles, - current_collector_dimension=1, + options={"dimensionality": 1}, form_factor="cylindrical", ) return get_mesh_for_testing( diff --git a/tests/unit/test_geometry/test_battery_geometry.py b/tests/unit/test_geometry/test_battery_geometry.py index 1ba3ddac03..9190e6a0c4 100644 --- a/tests/unit/test_geometry/test_battery_geometry.py +++ b/tests/unit/test_geometry/test_battery_geometry.py @@ -9,8 +9,10 @@ class TestBatteryGeometry(unittest.TestCase): def test_geometry_keys(self): for cc_dimension in [0, 1, 2]: geometry = pybamm.battery_geometry( - options={"particle size": "distribution"}, - current_collector_dimension=cc_dimension, + options={ + "particle size": "distribution", + "dimensionality": cc_dimension, + }, ) for domain_geoms in geometry.values(): all( @@ -23,8 +25,10 @@ def test_geometry(self): geo = pybamm.geometric_parameters for cc_dimension in [0, 1, 2]: geometry = pybamm.battery_geometry( - options={"particle size": "distribution"}, - current_collector_dimension=cc_dimension, + options={ + "particle size": "distribution", + "dimensionality": cc_dimension, + }, ) self.assertIsInstance(geometry, pybamm.Geometry) self.assertIn("negative electrode", geometry) @@ -45,7 +49,7 @@ def test_geometry(self): self.assertEqual(geometry["current collector"]["r_macro"]["position"], 1) geometry = pybamm.battery_geometry( - form_factor="cylindrical", current_collector_dimension=1 + form_factor="cylindrical", options={"dimensionality": 1} ) self.assertEqual(geometry["current collector"]["r_macro"]["min"], geo.r_inner) self.assertEqual(geometry["current collector"]["r_macro"]["max"], 1) @@ -61,11 +65,9 @@ def test_geometry(self): self.assertEqual(geometry["positive secondary particle"]["r_n_sec"]["max"], 1) def test_geometry_error(self): - with self.assertRaisesRegex(pybamm.GeometryError, "Invalid current"): - pybamm.battery_geometry(current_collector_dimension=4) with self.assertRaisesRegex(pybamm.GeometryError, "Invalid current"): pybamm.battery_geometry( - form_factor="cylindrical", current_collector_dimension=2 + form_factor="cylindrical", options={"dimensionality": 2} ) with self.assertRaisesRegex(pybamm.GeometryError, "Invalid form"): pybamm.battery_geometry(form_factor="triangle") @@ -88,7 +90,7 @@ def test_read_parameters(self): tab_p_z = geo.p.Centre_z_tab L_tab_p = geo.p.L_tab - geometry = pybamm.battery_geometry(current_collector_dimension=2) + geometry = pybamm.battery_geometry(options={"dimensionality": 2}) self.assertEqual( set([x.name for x in geometry.parameters]), diff --git a/tests/unit/test_meshes/test_meshes.py b/tests/unit/test_meshes/test_meshes.py index b04402128b..7317531ed2 100644 --- a/tests/unit/test_meshes/test_meshes.py +++ b/tests/unit/test_meshes/test_meshes.py @@ -99,7 +99,7 @@ def test_init_failure(self): pybamm.Mesh(geometry, submesh_types, {}) var_pts = {"x_n": 10, "x_s": 10, "x_p": 12} - geometry = pybamm.battery_geometry(current_collector_dimension=1) + geometry = pybamm.battery_geometry(options={"dimensionality": 1}) with self.assertRaisesRegex(KeyError, "Points not given"): pybamm.Mesh(geometry, submesh_types, var_pts) @@ -349,7 +349,7 @@ def test_1plus1D_tabs_left_right(self): ) geometry = pybamm.battery_geometry( - include_particles=False, current_collector_dimension=1 + include_particles=False, options={"dimensionality": 1} ) param.process_geometry(geometry) @@ -385,7 +385,7 @@ def test_1plus1D_tabs_right_left(self): ) geometry = pybamm.battery_geometry( - include_particles=False, current_collector_dimension=1 + include_particles=False, options={"dimensionality": 1} ) param.process_geometry(geometry) diff --git a/tests/unit/test_meshes/test_scikit_fem_submesh.py b/tests/unit/test_meshes/test_scikit_fem_submesh.py index 0e9c5561d4..63f57b437e 100644 --- a/tests/unit/test_meshes/test_scikit_fem_submesh.py +++ b/tests/unit/test_meshes/test_scikit_fem_submesh.py @@ -25,7 +25,7 @@ def test_mesh_creation(self): ) geometry = pybamm.battery_geometry( - include_particles=False, current_collector_dimension=2 + include_particles=False, options={"dimensionality": 2} ) param.process_geometry(geometry) @@ -68,7 +68,7 @@ def test_init_failure(self): "current collector": pybamm.MeshGenerator(pybamm.ScikitUniform2DSubMesh), } geometry = pybamm.battery_geometry( - include_particles=False, current_collector_dimension=2 + include_particles=False, options={"dimensionality": 2} ) with self.assertRaises(KeyError): pybamm.Mesh(geometry, submesh_types, {}) @@ -135,7 +135,7 @@ def test_tab_error(self): # check error raised if tab not on boundary geometry = pybamm.battery_geometry( - include_particles=False, current_collector_dimension=2 + include_particles=False, options={"dimensionality": 2} ) param.process_geometry(geometry) with self.assertRaises(pybamm.GeometryError): @@ -171,7 +171,7 @@ def test_tab_left_right(self): # check mesh can be built geometry = pybamm.battery_geometry( - include_particles=False, current_collector_dimension=2 + include_particles=False, options={"dimensionality": 2} ) param.process_geometry(geometry) pybamm.Mesh(geometry, submesh_types, var_pts) @@ -196,7 +196,7 @@ def test_mesh_creation(self): ) geometry = pybamm.battery_geometry( - include_particles=False, current_collector_dimension=2 + include_particles=False, options={"dimensionality": 2} ) param.process_geometry(geometry) @@ -274,7 +274,7 @@ def test_mesh_creation(self): ) geometry = pybamm.battery_geometry( - include_particles=False, current_collector_dimension=2 + include_particles=False, options={"dimensionality": 2} ) param.process_geometry(geometry) @@ -358,7 +358,7 @@ def test_mesh_creation(self): ) geometry = pybamm.battery_geometry( - include_particles=False, current_collector_dimension=2 + include_particles=False, options={"dimensionality": 2} ) param.process_geometry(geometry) diff --git a/tests/unit/test_models/test_full_battery_models/test_base_battery_model.py b/tests/unit/test_models/test_full_battery_models/test_base_battery_model.py index 6ef7a02760..b24026f251 100644 --- a/tests/unit/test_models/test_full_battery_models/test_base_battery_model.py +++ b/tests/unit/test_models/test_full_battery_models/test_base_battery_model.py @@ -388,6 +388,20 @@ def test_timescale(self): model = pybamm.BaseModel() self.assertEqual(model.timescale.evaluate(), 1) + def test_option_type(self): + # no entry gets default options + model = pybamm.BaseBatteryModel() + self.assertIsInstance(model.options, pybamm.BatteryModelOptions) + + # dict options get converted to BatteryModelOptions + model = pybamm.BaseBatteryModel({"thermal": "isothermal"}) + self.assertIsInstance(model.options, pybamm.BatteryModelOptions) + + # special dict types are not changed + options = pybamm.FuzzyDict({"thermal": "isothermal"}) + model = pybamm.BaseBatteryModel(options) + self.assertEqual(model.options, options) + class TestOptions(unittest.TestCase): def test_print_options(self): diff --git a/tests/unit/test_spatial_methods/test_scikit_finite_element.py b/tests/unit/test_spatial_methods/test_scikit_finite_element.py index e499ed2740..7af3a555e7 100644 --- a/tests/unit/test_spatial_methods/test_scikit_finite_element.py +++ b/tests/unit/test_spatial_methods/test_scikit_finite_element.py @@ -248,7 +248,7 @@ def test_manufactured_solution_cheb_grid(self): ) geometry = pybamm.battery_geometry( - include_particles=False, current_collector_dimension=2 + include_particles=False, options={"dimensionality": 2} ) param.process_geometry(geometry) @@ -309,7 +309,7 @@ def test_manufactured_solution_exponential_grid(self): ) geometry = pybamm.battery_geometry( - include_particles=False, current_collector_dimension=2 + include_particles=False, options={"dimensionality": 2} ) param.process_geometry(geometry) diff --git a/tests/unit/test_spatial_methods/test_spectral_volume.py b/tests/unit/test_spatial_methods/test_spectral_volume.py index c2e5f3396d..5ce7e78bad 100644 --- a/tests/unit/test_spatial_methods/test_spectral_volume.py +++ b/tests/unit/test_spatial_methods/test_spectral_volume.py @@ -78,7 +78,7 @@ def get_1p1d_mesh_for_testing( zpts=15, cc_submesh=pybamm.Uniform1DSubMesh, ): - geometry = pybamm.battery_geometry(current_collector_dimension=1) + geometry = pybamm.battery_geometry(options={"dimensionality": 1}) return get_mesh_for_testing( xpts=xpts, rpts=rpts, zpts=zpts, geometry=geometry, cc_submesh=cc_submesh )