def test_load_params(self): negative_electrode = pybamm.ParameterValues({}).read_parameters_csv( pybamm.get_parameters_filepath( "input/parameters/lithium_ion/negative_electrodes/li_metal_Xu2019/" "parameters.csv")) self.assertEqual( negative_electrode["Lithium metal concentration [mol.m-3]"], "76900") positive_electrode = pybamm.ParameterValues({}).read_parameters_csv( pybamm.get_parameters_filepath( "input/parameters/lithium_ion/positive_electrodes/NMC532_Xu2019/" "parameters.csv")) self.assertEqual(positive_electrode["Positive electrode porosity"], "0.331") electrolyte = pybamm.ParameterValues({}).read_parameters_csv( pybamm.get_parameters_filepath( "input/parameters/lithium_ion/electrolytes/lipf6_Valoen2005/" + "parameters.csv")) self.assertEqual(electrolyte["Cation transference number"], "0.38") cell = pybamm.ParameterValues({}).read_parameters_csv( pybamm.get_parameters_filepath( "input/parameters/lithium_ion/cells/li_metal_Xu2019/parameters.csv" )) self.assertAlmostEqual(cell["Negative electrode thickness [m]"], 700e-6)
def test_load_params(self): negative_electrode = pybamm.ParameterValues({}).read_parameters_csv( pybamm.get_parameters_filepath( "input/parameters/lithium_ion/negative_electrodes/graphite_Chen2020/" "parameters.csv")) self.assertEqual(negative_electrode["Negative electrode porosity"], "0.25") positive_electrode = pybamm.ParameterValues({}).read_parameters_csv( pybamm.get_parameters_filepath( "input/parameters/lithium_ion/positive_electrodes/nmc_Chen2020/" "parameters.csv")) self.assertEqual(positive_electrode["Positive electrode porosity"], "0.335") electrolyte = pybamm.ParameterValues({}).read_parameters_csv( pybamm.get_parameters_filepath( "input/parameters/lithium_ion/electrolytes/lipf6_Nyman2008/" + "parameters.csv")) self.assertEqual(electrolyte["Cation transference number"], "0.2594") cell = pybamm.ParameterValues({}).read_parameters_csv( pybamm.get_parameters_filepath( "input/parameters/lithium_ion/cells/LGM50_Chen2020/parameters.csv" )) self.assertAlmostEqual( cell["Negative current collector thickness [m]"], 12e-6)
def test_load_params(self): negative_electrode = pybamm.ParameterValues({}).read_parameters_csv( pybamm.get_parameters_filepath( "input/parameters/lithium-ion/negative_electrodes/graphite_Yang2017/" "parameters.csv")) self.assertEqual(negative_electrode["Negative electrode porosity"], "0.32") positive_electrode = pybamm.ParameterValues({}).read_parameters_csv( pybamm.get_parameters_filepath( "input/parameters/lithium-ion/positive_electrodes/nmc_Yang2017/" "parameters.csv")) self.assertEqual(positive_electrode["Positive electrode porosity"], "0.33") electrolyte = pybamm.ParameterValues({}).read_parameters_csv( pybamm.get_parameters_filepath( "input/parameters/lithium-ion/electrolytes/lipf6_Ecker2015/" + "parameters.csv")) self.assertEqual(electrolyte["Cation transference number"], "0.26") cell = pybamm.ParameterValues({}).read_parameters_csv( pybamm.get_parameters_filepath( "input/parameters/lithium-ion/cells/Yang2017/parameters.csv")) self.assertAlmostEqual( cell["Negative current collector thickness [m]"], 25e-6)
def test_load_params(self): anode = pybamm.ParameterValues({}).read_parameters_csv( pybamm.get_parameters_filepath( "input/parameters/lithium-ion/anodes/graphite_Ecker2015/parameters.csv" )) self.assertEqual(anode["Negative electrode porosity"], "0.329") path = "input/parameters/lithium-ion/cathodes/LiNiCoO2_Ecker2015/parameters.csv" cathode = pybamm.ParameterValues({}).read_parameters_csv( pybamm.get_parameters_filepath(path)) self.assertEqual(cathode["Positive electrode conductivity [S.m-1]"], "68.1") electrolyte = pybamm.ParameterValues({}).read_parameters_csv( pybamm.get_parameters_filepath( "input/parameters/lithium-ion/electrolytes/lipf6_Ecker2015/" + "parameters.csv")) self.assertEqual(electrolyte["Cation transference number"], "0.26") cell = pybamm.ParameterValues({}).read_parameters_csv( pybamm.get_parameters_filepath( "input/parameters/lithium-ion/cells/kokam_Ecker2015/parameters.csv" )) self.assertAlmostEqual( cell["Negative current collector thickness [m]"], 14e-6)
def test_load_params(self): negative_electrode = pybamm.ParameterValues({}).read_parameters_csv( pybamm.get_parameters_filepath( "input/parameters/lithium_ion/negative_electrodes/graphite_Ai2020/" "parameters.csv")) self.assertEqual(negative_electrode["Negative electrode porosity"], "0.33") positive_electrode = pybamm.ParameterValues({}).read_parameters_csv( pybamm.get_parameters_filepath( "input/parameters/lithium_ion/positive_electrodes/lico2_Ai2020/" "parameters.csv")) self.assertEqual(positive_electrode["Positive electrode porosity"], "0.32") electrolyte = pybamm.ParameterValues({}).read_parameters_csv( pybamm.get_parameters_filepath( "input/parameters/lithium_ion/electrolytes/lipf6_Enertech_Ai2020/" + "parameters.csv")) self.assertEqual(electrolyte["Cation transference number"], "0.38") cell = pybamm.ParameterValues({}).read_parameters_csv( pybamm.get_parameters_filepath( "input/parameters/lithium_ion/cells/Enertech_Ai2020/parameters.csv" )) self.assertAlmostEqual( cell["Negative current collector thickness [m]"], 10e-6)
def test_load_params(self): negative_electrode = pybamm.ParameterValues({}).read_parameters_csv( pybamm.get_parameters_filepath( "input/parameters/lithium_ion/negative_electrodes/graphite_Kim2011/" "parameters.csv")) self.assertEqual(negative_electrode["Negative electrode porosity"], "0.4") positive_electrode = pybamm.ParameterValues({}).read_parameters_csv( pybamm.get_parameters_filepath( "input/parameters/lithium_ion/positive_electrodes/nca_Kim2011/" "parameters.csv")) self.assertEqual(positive_electrode["Positive electrode porosity"], "0.4") electrolyte = pybamm.ParameterValues({}).read_parameters_csv( pybamm.get_parameters_filepath( "input/parameters/lithium_ion/electrolytes/lipf6_Kim2011/parameters.csv" )) self.assertEqual(electrolyte["Cation transference number"], "0.4") cell = pybamm.ParameterValues({}).read_parameters_csv( pybamm.get_parameters_filepath( "input/parameters/lithium_ion/cells/Kim2011/parameters.csv")) self.assertAlmostEqual( cell["Negative current collector thickness [m]"], 10**(-5))
def test_load_params(self): negative_electrode = pybamm.ParameterValues({}).read_parameters_csv( pybamm.get_parameters_filepath( "input/parameters/lithium_ion/" + "negative_electrodes/graphite_UMBL_Mohtat2020/parameters.csv")) self.assertEqual(negative_electrode["Negative electrode porosity"], "0.3") positive_electrode = pybamm.ParameterValues({}).read_parameters_csv( pybamm.get_parameters_filepath( "input/parameters/lithium_ion/" + "positive_electrodes/NMC_UMBL_Mohtat2020/parameters.csv")) self.assertEqual(positive_electrode["Positive electrode porosity"], "0.3") electrolyte = pybamm.ParameterValues({}).read_parameters_csv( pybamm.get_parameters_filepath( "input/parameters/lithium_ion/electrolytes/LiPF6_Mohtat2020/" + "parameters.csv")) self.assertEqual(electrolyte["Cation transference number"], "0.38") cell = pybamm.ParameterValues({}).read_parameters_csv( pybamm.get_parameters_filepath( "input/parameters/lithium_ion/cells/UMBL_Mohtat2020/parameters.csv" )) self.assertAlmostEqual( cell["Negative current collector thickness [m]"], 2.5e-05)
def test_load_params(self): anode = pybamm.ParameterValues({}).read_parameters_csv( pybamm.get_parameters_filepath( "input/parameters/lithium-ion/anodes/graphite_Chen2020/parameters.csv", )) self.assertEqual(anode["Reference temperature [K]"], "298.15") cathode = pybamm.ParameterValues({}).read_parameters_csv( pybamm.get_parameters_filepath( "input/parameters/lithium-ion/cathodes/nmc_Chen2020/parameters.csv", )) self.assertEqual(cathode["Reference temperature [K]"], "298.15") electrolyte = pybamm.ParameterValues({}).read_parameters_csv( pybamm.get_parameters_filepath( "input/parameters/lithium-ion/electrolytes/lipf6_Nyman2008/" + "parameters.csv", )) self.assertEqual(electrolyte["Reference temperature [K]"], "298.15") cell = pybamm.ParameterValues({}).read_parameters_csv( pybamm.get_parameters_filepath( "input/parameters/lithium-ion/cells/LGM50_Chen2020/parameters.csv", )) self.assertAlmostEqual( cell["Negative current collector thickness [m]"], 12e-6)
def test_get_parameters_filepath(self): tempfile_obj = tempfile.NamedTemporaryFile("w", dir=".") self.assertTrue( pybamm.get_parameters_filepath(tempfile_obj.name) == tempfile_obj.name) tempfile_obj.close() package_dir = os.path.join(pybamm.root_dir(), "pybamm") tempfile_obj = tempfile.NamedTemporaryFile("w", dir=package_dir) path = os.path.join(package_dir, tempfile_obj.name) self.assertTrue( pybamm.get_parameters_filepath(tempfile_obj.name) == path)
def test_load_params(self): cathode = pybamm.ParameterValues({}).read_parameters_csv( pybamm.get_parameters_filepath( "input/parameters/lithium-ion/cathodes/LFP_Prada2013/parameters.csv" )) self.assertEqual(cathode["Positive electrode porosity"], "0.12728395") cell = pybamm.ParameterValues({}).read_parameters_csv( pybamm.get_parameters_filepath( "input/parameters/lithium-ion/cells/A123_Lain2019/parameters.csv" )) self.assertAlmostEqual( cell["Negative current collector thickness [m]"], 1e-5)
def test_drive_cycle_data(self): model = pybamm.lithium_ion.SPM() param = model.default_parameter_values param["Current function [A]"] = "[current data]US06" drive_cycle = pd.read_csv( pybamm.get_parameters_filepath( os.path.join("input", "drive_cycles", "US06.csv")), comment="#", skip_blank_lines=True, header=None, ) time_data = drive_cycle.values[:, 0] sim = pybamm.Simulation(model, parameter_values=param) # check solution is returned at the times in the data sim.solve() 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 # smallest gap in the data sim.reset() with self.assertWarns(pybamm.SolverWarning): sim.solve(t_eval=np.linspace(0, 1, 100)) # check warning raised if t_eval doesnt contain time_data , but has a finer # resolution (can still solve, but good for users to know they dont have # the solution returned at the data points) sim.reset() with self.assertWarns(pybamm.SolverWarning): sim.solve(t_eval=np.linspace(0, time_data[-1], 800))
def test_add_param(self): # Read a parameter file thta is shipped with PyBaMM param_filename = pybamm.get_parameters_filepath( "input/parameters/lithium-ion/anodes/" "graphite_mcmb2528_Marquis2019/parameters.csv", ) anode = pybamm.ParameterValues({}).read_parameters_csv(param_filename) # Write these parameters in current working dir. to mimic # user-defined parameters tempdir = tempfile.TemporaryDirectory() new_parameter_file = os.path.join(tempdir.name, "parameters.csv") with open(new_parameter_file, "w", newline="") as csvfile: fieldnames = ["Name [units]", "Value"] writer = csv.writer(csvfile) writer.writerow(fieldnames) for row in anode.items(): writer.writerow(row) # Use pybamm command line to add new parameters under # test_parameters_dir directory cmd = [ "pybamm_add_parameter", "-f", tempdir.name, "lithium-ion", "anodes" ] subprocess.run(cmd, check=True) # Check that the new parameters can be accessed from the package # and that content is correct new_parameter_filename = pybamm.get_parameters_filepath( os.path.join( "input", "parameters", "lithium-ion", "anodes", os.path.basename(tempdir.name), "parameters.csv", ), ) new_anode = pybamm.ParameterValues( {}).read_parameters_csv(new_parameter_filename) self.assertEqual(new_anode["Reference temperature [K]"], "298.15") # Clean up directories tempdir.cleanup() # Remove temporary local directory os.remove(new_parameter_filename) # Remove parameters.csv file os.rmdir( os.path.dirname(new_parameter_filename)) # Remove (now empty) dir
def update_from_chemistry(self, chemistry): """ Load standard set of components from a 'chemistry' dictionary """ base_chemistry = chemistry["chemistry"] # Create path to file path = os.path.join( pybamm.root_dir(), "pybamm", "input", "parameters", base_chemistry ) # Load each component name component_groups = [ "cell", "anode", "cathode", "separator", "electrolyte", "experiment", ] # add sei parameters if provided if "sei" in chemistry: component_groups += ["sei"] for component_group in component_groups: # Make sure component is provided try: component = chemistry[component_group] except KeyError: raise KeyError( "must provide '{}' parameters for {} chemistry".format( component_group, base_chemistry ) ) # Create path to component and load values component_path = os.path.join(path, component_group + "s", component) component_params = self.read_parameters_csv( pybamm.get_parameters_filepath( os.path.join(component_path, "parameters.csv") ) ) # Update parameters, making sure to check any conflicts self.update( component_params, check_conflict=True, check_already_exists=False, path=component_path, ) # register (list of) citations if "citation" in chemistry: citations = chemistry["citation"] if not isinstance(citations, list): citations = [citations] for citation in citations: pybamm.citations.register(citation)
def test_read_parameters_csv(self): data = pybamm.ParameterValues({}).read_parameters_csv( pybamm.get_parameters_filepath( os.path.join( "input", "parameters", "lithium-ion", "cathodes", "lico2_Marquis2019", "parameters.csv", ))) self.assertEqual(data["Positive electrode porosity"], "0.3")
def test_read_parameters_csv(self): data = pybamm.ParameterValues({}).read_parameters_csv( pybamm.get_parameters_filepath( os.path.join( "input", "parameters", "lithium-ion", "cathodes", "lico2_Marquis2019", "parameters.csv", ))) self.assertEqual(data["Reference temperature [K]"], "298.15")
def test_load_params(self): anode = pybamm.ParameterValues({}).read_parameters_csv( pybamm.get_parameters_filepath( "input/parameters/lithium-ion/anodes/graphite_Kim2011/parameters.csv", )) self.assertEqual(anode["Reference temperature [K]"], "298.15") cathode = pybamm.ParameterValues({}).read_parameters_csv( pybamm.get_parameters_filepath( "input/parameters/lithium-ion/cathodes/nca_Kim2011/parameters.csv", )) self.assertEqual(cathode["Reference temperature [K]"], "298.15") electrolyte = pybamm.ParameterValues({}).read_parameters_csv( pybamm.get_parameters_filepath( "input/parameters/lithium-ion/electrolytes/lipf6_Kim2011/parameters.csv" )) self.assertEqual(electrolyte["Reference temperature [K]"], "298.15") cell = pybamm.ParameterValues({}).read_parameters_csv( pybamm.get_parameters_filepath( "input/parameters/lithium-ion/cells/Kim2011/parameters.csv")) self.assertAlmostEqual( cell["Negative current collector thickness [m]"], 10**(-5))
def test_init(self): # from dict param = pybamm.ParameterValues({"a": 1}) self.assertEqual(param["a"], 1) self.assertEqual(list(param.keys())[0], "a") self.assertEqual(list(param.values())[0], 1) self.assertEqual(list(param.items())[0], ("a", 1)) # from file param = pybamm.ParameterValues(values=pybamm.get_parameters_filepath( "input/parameters/lithium-ion/cathodes/lico2_Marquis2019/" + "parameters.csv", )) self.assertEqual(param["Reference temperature [K]"], 298.15) # values vs chemistry with self.assertRaisesRegex( ValueError, "values and chemistry cannot both be None"): pybamm.ParameterValues() with self.assertRaisesRegex( ValueError, "Only one of values and chemistry can be provided."): pybamm.ParameterValues(values=1, chemistry={})
def test_read_strings(self): # Import drive cycle from file drive_cycle = pd.read_csv( pybamm.get_parameters_filepath( os.path.join("input", "drive_cycles", "US06.csv")), comment="#", header=None, ).to_numpy() experiment = pybamm.Experiment( [ "Discharge at 1C for 0.5 hours", "Discharge at C/20 for 0.5 hours", "Charge at 0.5 C for 45 minutes", "Discharge at 1 A for 0.5 hours", "Charge at 200 mA for 45 minutes (1 minute period)", "Discharge at 1W for 0.5 hours", "Charge at 200mW for 45 minutes", "Rest for 10 minutes (5 minute period)", "Hold at 1V for 20 seconds", "Charge at 1 C until 4.1V", "Hold at 4.1 V until 50mA", "Hold at 3V until C/50", "Discharge at C/3 for 2 hours or until 2.5 V", "Run US06 (A)", "Run US06 (V) for 5 minutes", "Run US06 (W) for 0.5 hours", ], {"test": "test"}, drive_cycles={"US06": drive_cycle}, period="20 seconds", ) # Calculation for operating conditions of drive cycle time_0 = drive_cycle[:, 0][-1] period_0 = numpy.min(numpy.diff(drive_cycle[:, 0])) drive_cycle_1 = experiment.extend_drive_cycle(drive_cycle, end_time=300) time_1 = drive_cycle_1[:, 0][-1] period_1 = numpy.min(numpy.diff(drive_cycle_1[:, 0])) drive_cycle_2 = experiment.extend_drive_cycle(drive_cycle, end_time=1800) time_2 = drive_cycle_2[:, 0][-1] period_2 = numpy.min(numpy.diff(drive_cycle_2[:, 0])) self.assertEqual( experiment.operating_conditions[:-3], [ (1, "C", 1800.0, 20.0), (0.05, "C", 1800.0, 20.0), (-0.5, "C", 2700.0, 20.0), (1, "A", 1800.0, 20.0), (-0.2, "A", 2700.0, 60.0), (1, "W", 1800.0, 20.0), (-0.2, "W", 2700.0, 20.0), (0, "A", 600.0, 300.0), (1, "V", 20.0, 20.0), (-1, "C", None, 20.0), (4.1, "V", None, 20.0), (3, "V", None, 20.0), (1 / 3, "C", 7200.0, 20.0), ], ) # Check drive cycle operating conditions self.assertTrue( ((experiment.operating_conditions[-3][0] == drive_cycle).all() & (experiment.operating_conditions[-3][1] == "A") & (experiment.operating_conditions[-3][2] == time_0).all() & (experiment.operating_conditions[-3][3] == period_0).all() & (experiment.operating_conditions[-2][0] == drive_cycle_1).all() & (experiment.operating_conditions[-2][1] == "V") & (experiment.operating_conditions[-2][2] == time_1).all() & (experiment.operating_conditions[-2][3] == period_1).all() & (experiment.operating_conditions[-1][0] == drive_cycle_2).all() & (experiment.operating_conditions[-1][1] == "W") & (experiment.operating_conditions[-1][2] == time_2).all() & (experiment.operating_conditions[-1][3] == period_2).all())) self.assertEqual( experiment.events, [ None, None, None, None, None, None, None, None, None, (4.1, "V"), (0.05, "A"), (0.02, "C"), (2.5, "V"), None, None, None, ], ) self.assertEqual(experiment.parameters, {"test": "test"}) self.assertEqual(experiment.period, 20)
def update(self, values, check_conflict=False, check_already_exists=True, path=""): """ Update parameter dictionary, while also performing some basic checks. Parameters ---------- values : dict Dictionary of parameter values to update parameter dictionary with check_conflict : bool, optional Whether to check that a parameter in `values` has not already been defined in the parameter class when updating it, and if so that its value does not change. This is set to True during initialisation, when parameters are combined from different sources, and is False by default otherwise check_already_exists : bool, optional Whether to check that a parameter in `values` already exists when trying to update it. This is to avoid cases where an intended change in the parameters is ignored due a typo in the parameter name, and is True by default but can be manually overridden. 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 if (check_conflict is True and name in self.keys() and not (self[name] == float(value) or self[name] == value)): raise ValueError( "parameter '{}' already defined with value '{}'".format( name, self[name])) # check parameter already exists (for updating parameters) if check_already_exists is True: try: self._dict_items[name] except KeyError as err: raise KeyError( "Cannot update parameter '{}' as it does not ".format( name) + "have a default value. ({}). If you are ".format( err.args[0]) + "sure you want to update this parameter, use " + "param.update({{name: value}}, check_already_exists=False)" ) # if no conflicts, update, loading functions and data if they are specified # Functions are flagged with the string "[function]" if isinstance(value, str): if value.startswith("[function]"): loaded_value = pybamm.load_function( os.path.join(path, value[10:])) self._dict_items[name] = loaded_value values[name] = loaded_value # Data is flagged with the string "[data]" or "[current data]" elif value.startswith("[current data]") or value.startswith( "[data]"): if value.startswith("[current data]"): data_path = os.path.join(pybamm.root_dir(), "pybamm", "input", "drive_cycles") filename = os.path.join(data_path, value[14:] + ".csv") function_name = value[14:] else: filename = os.path.join(path, value[6:] + ".csv") function_name = value[6:] filename = pybamm.get_parameters_filepath(filename) data = pd.read_csv(filename, comment="#", skip_blank_lines=True, header=None).to_numpy() # Save name and data self._dict_items[name] = (function_name, data) values[name] = (function_name, data) elif value == "[input]": self._dict_items[name] = pybamm.InputParameter(name) # Anything else should be a converted to a float else: self._dict_items[name] = float(value) values[name] = float(value) else: self._dict_items[name] = value # reset processed symbols self._processed_symbols = {}
import scipy.interpolate as interp # change working directory to the root of pybamm os.chdir(pybamm.root_dir()) "-----------------------------------------------------------------------------" "Pick C_rate and load comsol data" # C_rate # NOTE: the results in pybamm stop when a voltage cutoff is reached, so # for higher C-rate the pybamm solution may stop before the comsol solution C_rates = {"01": 0.1, "05": 0.5, "1": 1, "2": 2, "3": 3} C_rate = "1" # choose the key from the above dictionary of available results # load the comsol results comsol_results_path = pybamm.get_parameters_filepath( "input/comsol_results/comsol_{}C.pickle".format(C_rate)) comsol_variables = pickle.load(open(comsol_results_path, "rb")) "-----------------------------------------------------------------------------" "Create and solve pybamm model" # load model and geometry pybamm.set_logging_level("INFO") pybamm_model = pybamm.lithium_ion.DFN() geometry = pybamm_model.default_geometry # load parameters and process model and geometry param = pybamm_model.default_parameter_values param["Electrode width [m]"] = 1 param["Electrode height [m]"] = 1 param["Current function [A]"] = 24 * C_rates[C_rate]
def test_cycle_summary_variables(self): # Test cycle_summary_variables works for different combinations of data and # function OCPs experiment = pybamm.Experiment([ ( "Discharge at 1C until 3.3V", "Charge at C/3 until 4.0V", "Hold at 4.0V until C/10", ), ] * 5, ) model = pybamm.lithium_ion.SPM() # Chen 2020 plating: pos = function, neg = data param = pybamm.ParameterValues( chemistry=pybamm.parameter_sets.Chen2020_plating) sim = pybamm.Simulation(model, experiment=experiment, parameter_values=param) sim.solve(solver=pybamm.CasadiSolver("fast with events"), save_at_cycles=2) # Chen 2020: pos = function, neg = function param = pybamm.ParameterValues( chemistry=pybamm.parameter_sets.Chen2020) sim = pybamm.Simulation(model, experiment=experiment, parameter_values=param) sim.solve(solver=pybamm.CasadiSolver("fast with events"), save_at_cycles=2) # Chen 2020 with data: pos = data, neg = data # Load negative electrode OCP data filename = os.path.join( pybamm.root_dir(), "pybamm", "input", "parameters", "lithium_ion", "negative_electrodes", "graphite_Chen2020", "graphite_LGM50_ocp_Chen2020.csv", ) function_name = "graphite_Chen2020" filename = pybamm.get_parameters_filepath(filename) data = pd.read_csv(filename, comment="#", skip_blank_lines=True, header=None).to_numpy() param["Negative electrode OCP [V]"] = (function_name, data) # Load positive electrode OCP data filename = os.path.join( pybamm.root_dir(), "pybamm", "input", "parameters", "lithium_ion", "positive_electrodes", "nmc_Chen2020", "nmc_LGM50_ocp_Chen2020.csv", ) function_name = "nmc_LGM50_ocp_Chen2020.csv" filename = pybamm.get_parameters_filepath(filename) data = pd.read_csv(filename, comment="#", skip_blank_lines=True, header=None).to_numpy() param["Positive electrode OCP [V]"] = (function_name, data) sim = pybamm.Simulation(model, experiment=experiment, parameter_values=param) sim.solve(solver=pybamm.CasadiSolver("safe"), save_at_cycles=2)