From 01dc550eb1024a0c72050c2b6b09781dcbe7553b Mon Sep 17 00:00:00 2001 From: mleot Date: Tue, 5 Dec 2023 12:08:37 -0800 Subject: [PATCH 01/43] first tests passed --- .../full_battery_models/base_battery_model.py | 4 +- .../lithium_ion/base_lithium_ion_model.py | 2 + .../open_circuit_potential/__init__.py | 1 + .../open_circuit_potential/plett_ocp.py | 114 ++++++++++++++++++ pybamm/parameters/lithium_ion_parameters.py | 27 +++++ .../test_lithium_ion/test_mpm.py | 18 +++ .../base_lithium_ion_tests.py | 4 + .../test_lithium_ion/test_dfn.py | 7 ++ .../test_lithium_ion/test_mpm.py | 7 ++ 9 files changed, 182 insertions(+), 2 deletions(-) create mode 100644 pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py diff --git a/pybamm/models/full_battery_models/base_battery_model.py b/pybamm/models/full_battery_models/base_battery_model.py index b174ef581c..c2841c5ced 100644 --- a/pybamm/models/full_battery_models/base_battery_model.py +++ b/pybamm/models/full_battery_models/base_battery_model.py @@ -103,7 +103,7 @@ class BatteryModelOptions(pybamm.FuzzyDict): reactions. * "open-circuit potential" : str Sets the model for the open circuit potential. Can be "single" - (default), "current sigmoid", or "MSMR". If "MSMR" then the "particle" + (default), "current sigmoid", "Plett", or "MSMR". If "MSMR" then the "particle" option must also be "MSMR". A 2-tuple can be provided for different behaviour in negative and positive electrodes. * "operating mode" : str @@ -264,7 +264,7 @@ def __init__(self, extra_options): "stress and reaction-driven", ], "number of MSMR reactions": ["none"], - "open-circuit potential": ["single", "current sigmoid", "MSMR"], + "open-circuit potential": ["single", "current sigmoid", "MSMR", "Plett"], "operating mode": [ "current", "voltage", 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 fbe19b0d42..39a850fb6a 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 @@ -248,6 +248,8 @@ def set_open_circuit_potential_submodel(self): ocp_model = ocp_submodels.SingleOpenCircuitPotential elif ocp_option == "current sigmoid": ocp_model = ocp_submodels.CurrentSigmoidOpenCircuitPotential + elif ocp_option == "Plett": + ocp_model = ocp_submodels.PlettOpenCircuitPotential elif ocp_option == "MSMR": ocp_model = ocp_submodels.MSMROpenCircuitPotential self.submodels[f"{domain} {phase} open-circuit potential"] = ocp_model( diff --git a/pybamm/models/submodels/interface/open_circuit_potential/__init__.py b/pybamm/models/submodels/interface/open_circuit_potential/__init__.py index 5f8a409bba..0004d9f2b5 100644 --- a/pybamm/models/submodels/interface/open_circuit_potential/__init__.py +++ b/pybamm/models/submodels/interface/open_circuit_potential/__init__.py @@ -2,3 +2,4 @@ from .single_ocp import SingleOpenCircuitPotential from .current_sigmoid_ocp import CurrentSigmoidOpenCircuitPotential from .msmr_ocp import MSMROpenCircuitPotential +from .plett_ocp import PlettOpenCircuitPotential diff --git a/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py b/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py new file mode 100644 index 0000000000..1e9af660ec --- /dev/null +++ b/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py @@ -0,0 +1,114 @@ +# +# OCP with empiral hysteresis function, and hysteresis state function +# +import pybamm +from . import BaseOpenCircuitPotential + + +class PlettOpenCircuitPotential(BaseOpenCircuitPotential): + def get_fundamental_variables(self): + domain, Domain = self.domain_Domain + phase_name = self.phase_name + h = pybamm.Variable(f'{Domain} electrode {phase_name}hysteresis state') + # ocp_eq = pybamm.Variable(f'{Domain} electrode {phase_name}equilibrium OCP [V]') + # ocp_eq_bulk = pybamm.Variable(f'{Domain} electrode {phase_name}bulk equilibrium OCP [V]') + # dQdU = pybamm.Variable(f'{Domain} electrode {phase_name}differential capacity [A.s.V-1]') + return {f'{Domain} electrode {phase_name}hysteresis state':h, + # f'{Domain} electrode {phase_name}equilibrium OCP [V]':ocp_eq, + # f'{Domain} electrode {phase_name}bulk equilibrium OCP [V]':ocp_eq_bulk, + # f'{Domain} electrode {phase_name}differential capacity [A.s.V-1]':dQdU + } + + def get_coupled_variables(self, variables): + domain, Domain = self.domain_Domain + phase_name = self.phase_name + + if self.reaction == "lithium-ion main": + T = variables[f"{Domain} electrode temperature [K]"] + #! custom + # capacity = variables['Discharge capacity [A.h]'] + h = variables[f'{Domain} electrode {phase_name}hysteresis state'] + #! Custom + # For "particle-size distribution" models, take distribution version + # of c_s_surf that depends on particle size. + domain_options = getattr(self.options, domain) + if domain_options["particle size"] == "distribution": + sto_surf = variables[ + f"{Domain} {phase_name}particle surface stoichiometry distribution" + ] + # If variable was broadcast, take only the orphan + if isinstance(sto_surf, pybamm.Broadcast) and isinstance( + T, pybamm.Broadcast + ): + sto_surf = sto_surf.orphans[0] + T = T.orphans[0] + T = pybamm.PrimaryBroadcast(T, [f"{domain} particle size"]) + # h = pybamm.PrimaryBroadcast(h, [f'{domain} particle size']) + else: + sto_surf = variables[ + f"{Domain} {phase_name}particle surface stoichiometry" + ] + # If variable was broadcast, take only the orphan + if isinstance(sto_surf, pybamm.Broadcast) and isinstance( + T, pybamm.Broadcast + ): + sto_surf = sto_surf.orphans[0] + T = T.orphans[0] + + ocp_surf_eq = self.phase_param.U(sto_surf, T) + dUdT = self.phase_param.dUdT(sto_surf) + + # Bulk OCP is from the average SOC and temperature + sto_bulk = variables[f"{Domain} electrode {phase_name}stoichiometry"] + T_bulk = pybamm.xyz_average(pybamm.size_average(T)) + ocp_bulk_eq = self.phase_param.U(sto_bulk, T_bulk) + + #! Custom + H = self.phase_param.H(sto_bulk) + variables[f'{Domain} electrode {phase_name}equilibrium OCP [V]'] = ocp_surf_eq + variables[f'{Domain} electrode {phase_name}bulk equilibrium OCP [V]'] = ocp_bulk_eq + variables[f'{Domain} electrode {phase_name} OCP hysteresis [V]'] = H + # dQdU = variables[f'{Domain} electrode {phase_name}differential capacity [A.s.V-1]'] + + dU = pybamm.source(1,ocp_bulk_eq.diff(sto_bulk)) + Q = self.phase_param.Q(sto_bulk) + dQ = Q.diff(sto_bulk) + dQdU = dQ/dU + variables[f'{Domain} electrode {phase_name}differential capacity [A.s.V-1]'] = dQdU + ocp_surf = ocp_surf_eq + H * h + ocp_bulk = ocp_bulk_eq + H * h + #! Custom + + variables.update(self._get_standard_ocp_variables(ocp_surf, ocp_bulk, dUdT)) + return variables + + # def set_algebraic(self, variables): + # domain, Domain = self.domain_Domain + # phase_name = self.phase_name + # dQdU = variables[f'{Domain} electrode {phase_name}differential capacity [A.s.V-1]'] + + # return super().set_algebraic(variables) + + def set_rhs(self, variables): + domain, Domain = self.domain_Domain + phase_name = self.phase_name + + current = self.param.current_with_time + + Q_cell = variables[f'{Domain} electrode capacity [A.h]'] + dQdU = variables[f'{Domain} electrode {phase_name}differential capacity [A.s.V-1]'] + K = self.phase_param.K + K_x = self.phase_param.K_x + h = variables[f'{Domain} electrode {phase_name}hysteresis state'] + + dhdt = K * (current/(Q_cell*(dQdU**K_x)))*(1-pybamm.sign(current)*h) + self.rhs[h] = dhdt + + def set_initial_conditions(self, variables): + domain, Domain = self.domain_Domain + phase_name = self.phase_name + h = pybamm.Variable(f'{Domain} electrode {phase_name}hysteresis state') + self.initial_conditions[h] = pybamm.Scalar(0) + + # def set_boundary_conditions(self, variables): + # self.boundary_conditions[] diff --git a/pybamm/parameters/lithium_ion_parameters.py b/pybamm/parameters/lithium_ion_parameters.py index 12196c4044..0eb7da150d 100644 --- a/pybamm/parameters/lithium_ion_parameters.py +++ b/pybamm/parameters/lithium_ion_parameters.py @@ -535,6 +535,10 @@ def _set_parameters(self): eps_c_init_av = pybamm.xyz_average( self.epsilon_s * pybamm.r_average(self.c_init) ) + # if self.options['open-circuit potential'] == 'Plett': + self.K = pybamm.Parameter(f'{pref}{Domain} particle hysteresis decay rate') + self.K_x = pybamm.Parameter(f'{pref}{Domain} particle hysteresis switching factor') + self.h_init = pybamm.Scalar(0) if self.options["open-circuit potential"] != "MSMR": self.U_init = self.U(self.sto_init_av, main.T_init) @@ -630,6 +634,27 @@ def U(self, sto, T, lithiation=None): out.print_name = r"U_\mathrm{p}(c^\mathrm{surf}_\mathrm{s,p}, T)" return out + def H(self, sto): + """Dimensional hysteresis [V]""" + Domain = self.domain.capitalize() + # tol = pybamm.settings.tolerances["U__c_s"] + # sto = pybamm.maximum(pybamm.minimum(sto,1-tol),tol) + inputs = {f"{self.phase_prefactor}{Domain} particle stoichiometry": sto} + h_ref = pybamm.FunctionParameter( + f"{self.phase_prefactor}{Domain} electrode OCP hysteresis [V]", inputs + ) + return h_ref + + def Q(self, sto): + """Capacity change as a function of stoichiometry""" + c_max = self.c_max + epsilon_s_av = self.epsilon_s_av + V_electrode = self.main_param.A_cc*self.domain_param.L + Li_max = c_max * V_electrode * epsilon_s_av + Q_max = Li_max * self.main_param.F / 3600 + return Q_max * sto + + def dUdT(self, sto): """ Dimensional entropic change of the open-circuit potential [V.K-1] @@ -645,6 +670,8 @@ def dUdT(self, sto): inputs, ) + # def dQdU(self,sto) + def X_j(self, index): "Available host sites indexed by reaction j" domain = self.domain diff --git a/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_mpm.py b/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_mpm.py index 18d773bed2..0431a75fe7 100644 --- a/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_mpm.py +++ b/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_mpm.py @@ -66,6 +66,24 @@ def test_current_sigmoid_ocp(self): modeltest = tests.StandardModelTest(model, parameter_values=parameter_values) modeltest.test_all(skip_output_tests=True) + def test_plett_ocp(self): + options = {"open-circuit potential": ("Plett", "single")} + model = pybamm.lithium_ion.MPM(options) + parameter_values = pybamm.ParameterValues("Chen2020") + parameter_values = pybamm.get_size_distribution_parameters(parameter_values) + parameter_values.update( + { + "Negative electrode OCP [V]" + "": parameter_values["Negative electrode OCP [V]"], + "Negative particle hysteresis decay rate": 1, + "Negative particle hysteresis switching factor":1, + "Negative electrode OCP hysteresis [V]":lambda sto: 1, + }, + check_already_exists=False, + ) + modeltest = tests.StandardModelTest(model, parameter_values=parameter_values) + modeltest.test_all(skip_output_tests=True) + def test_voltage_control(self): options = {"operating mode": "voltage"} model = pybamm.lithium_ion.MPM(options) diff --git a/tests/unit/test_models/test_full_battery_models/test_lithium_ion/base_lithium_ion_tests.py b/tests/unit/test_models/test_full_battery_models/test_lithium_ion/base_lithium_ion_tests.py index f4e3c3cceb..51600161bd 100644 --- a/tests/unit/test_models/test_full_battery_models/test_lithium_ion/base_lithium_ion_tests.py +++ b/tests/unit/test_models/test_full_battery_models/test_lithium_ion/base_lithium_ion_tests.py @@ -368,6 +368,10 @@ def test_well_posed_current_sigmoid_ocp(self): options = {"open-circuit potential": "current sigmoid"} self.check_well_posedness(options) + def test_well_posed_plett_ocp(self): + options = {"open-circuit potential": "Plett"} + self.check_well_posedness(options) + def test_well_posed_msmr(self): options = { "open-circuit potential": "MSMR", diff --git a/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_dfn.py b/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_dfn.py index d7e95247e0..3c42f5ca4f 100644 --- a/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_dfn.py +++ b/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_dfn.py @@ -35,6 +35,13 @@ def test_well_posed_current_sigmoid_ocp_with_psd(self): } self.check_well_posedness(options) + def test_well_posed_plett_ocp_with_psd(self): + options = { + "open-circuit potential": "Plett", + "particle size": "distribution", + } + self.check_well_posedness(options) + def test_well_posed_external_circuit_explicit_power(self): options = {"operating mode": "explicit power"} self.check_well_posedness(options) diff --git a/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_mpm.py b/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_mpm.py index 442817e354..a0b56cf340 100644 --- a/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_mpm.py +++ b/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_mpm.py @@ -118,6 +118,13 @@ def test_msmr(self): model = pybamm.lithium_ion.MPM(options) model.check_well_posedness() + def test_plett_ocp(self): + options = { + "open-circuit potential": "Plett", + } + model = pybamm.lithium_ion.MPM(options) + model.check_well_posedness() + class TestMPMExternalCircuits(TestCase): def test_well_posed_voltage(self): From 809af0120f03a323c4cfad5257f8e88cbd3d801b Mon Sep 17 00:00:00 2001 From: mleot Date: Tue, 5 Dec 2023 16:28:39 -0800 Subject: [PATCH 02/43] updated citations --- pybamm/CITATIONS.bib | 13 +++++++++++++ .../lithium_ion/base_lithium_ion_model.py | 1 + 2 files changed, 14 insertions(+) diff --git a/pybamm/CITATIONS.bib b/pybamm/CITATIONS.bib index 21740584b5..4ef2106c10 100644 --- a/pybamm/CITATIONS.bib +++ b/pybamm/CITATIONS.bib @@ -704,3 +704,16 @@ @article{landesfeind2019temperature year={2019}, publisher={The Electrochemical Society} } + +@article{WYCISK2022105016, +title = {Modified Plett-model for modeling voltage hysteresis in lithium-ion cells}, +journal = {Journal of Energy Storage}, +volume = {52}, +pages = {105016}, +year = {2022}, +issn = {2352-152X}, +doi = {https://doi.org/10.1016/j.est.2022.105016}, +url = {https://www.sciencedirect.com/science/article/pii/S2352152X22010192}, +author = {Dominik Wycisk and Marc Oldenburger and Marc Gerry Stoye and Toni Mrkonjic and Arnulf Latz}, +keywords = {Lithium-ion battery, Voltage hysteresis, Plett-model, Silicon–graphite anode}, +} 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 39a850fb6a..eca0bbf371 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 @@ -249,6 +249,7 @@ def set_open_circuit_potential_submodel(self): elif ocp_option == "current sigmoid": ocp_model = ocp_submodels.CurrentSigmoidOpenCircuitPotential elif ocp_option == "Plett": + pybamm.citations.register('Wycisk2022') ocp_model = ocp_submodels.PlettOpenCircuitPotential elif ocp_option == "MSMR": ocp_model = ocp_submodels.MSMROpenCircuitPotential From a9ce212dc56ed5d8078d78b1d5c07306814d60cb Mon Sep 17 00:00:00 2001 From: mleot Date: Tue, 5 Dec 2023 17:13:37 -0800 Subject: [PATCH 03/43] clean up ocp script --- .../open_circuit_potential/plett_ocp.py | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py b/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py index 1e9af660ec..f39d24b3c9 100644 --- a/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py +++ b/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py @@ -1,5 +1,5 @@ # -# OCP with empiral hysteresis function, and hysteresis state function +# from Wycisk 2022 # import pybamm from . import BaseOpenCircuitPotential @@ -10,14 +10,7 @@ def get_fundamental_variables(self): domain, Domain = self.domain_Domain phase_name = self.phase_name h = pybamm.Variable(f'{Domain} electrode {phase_name}hysteresis state') - # ocp_eq = pybamm.Variable(f'{Domain} electrode {phase_name}equilibrium OCP [V]') - # ocp_eq_bulk = pybamm.Variable(f'{Domain} electrode {phase_name}bulk equilibrium OCP [V]') - # dQdU = pybamm.Variable(f'{Domain} electrode {phase_name}differential capacity [A.s.V-1]') - return {f'{Domain} electrode {phase_name}hysteresis state':h, - # f'{Domain} electrode {phase_name}equilibrium OCP [V]':ocp_eq, - # f'{Domain} electrode {phase_name}bulk equilibrium OCP [V]':ocp_eq_bulk, - # f'{Domain} electrode {phase_name}differential capacity [A.s.V-1]':dQdU - } + return {f'{Domain} electrode {phase_name}hysteresis state':h,} def get_coupled_variables(self, variables): domain, Domain = self.domain_Domain @@ -25,10 +18,7 @@ def get_coupled_variables(self, variables): if self.reaction == "lithium-ion main": T = variables[f"{Domain} electrode temperature [K]"] - #! custom - # capacity = variables['Discharge capacity [A.h]'] h = variables[f'{Domain} electrode {phase_name}hysteresis state'] - #! Custom # For "particle-size distribution" models, take distribution version # of c_s_surf that depends on particle size. domain_options = getattr(self.options, domain) @@ -43,7 +33,7 @@ def get_coupled_variables(self, variables): sto_surf = sto_surf.orphans[0] T = T.orphans[0] T = pybamm.PrimaryBroadcast(T, [f"{domain} particle size"]) - # h = pybamm.PrimaryBroadcast(h, [f'{domain} particle size']) + h = pybamm.PrimaryBroadcast(h, [f'{domain} particle size']) else: sto_surf = variables[ f"{Domain} {phase_name}particle surface stoichiometry" @@ -63,7 +53,6 @@ def get_coupled_variables(self, variables): T_bulk = pybamm.xyz_average(pybamm.size_average(T)) ocp_bulk_eq = self.phase_param.U(sto_bulk, T_bulk) - #! Custom H = self.phase_param.H(sto_bulk) variables[f'{Domain} electrode {phase_name}equilibrium OCP [V]'] = ocp_surf_eq variables[f'{Domain} electrode {phase_name}bulk equilibrium OCP [V]'] = ocp_bulk_eq @@ -77,7 +66,6 @@ def get_coupled_variables(self, variables): variables[f'{Domain} electrode {phase_name}differential capacity [A.s.V-1]'] = dQdU ocp_surf = ocp_surf_eq + H * h ocp_bulk = ocp_bulk_eq + H * h - #! Custom variables.update(self._get_standard_ocp_variables(ocp_surf, ocp_bulk, dUdT)) return variables From 13875ce2386fd990f18553281071f3a79910ef40 Mon Sep 17 00:00:00 2001 From: mleot Date: Thu, 7 Dec 2023 14:12:31 -0800 Subject: [PATCH 04/43] might be step in wrong direction --- .../open_circuit_potential/plett_ocp.py | 71 ++++++++++++++----- 1 file changed, 52 insertions(+), 19 deletions(-) diff --git a/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py b/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py index f39d24b3c9..f5d0ce490a 100644 --- a/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py +++ b/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py @@ -9,12 +9,16 @@ class PlettOpenCircuitPotential(BaseOpenCircuitPotential): def get_fundamental_variables(self): domain, Domain = self.domain_Domain phase_name = self.phase_name - h = pybamm.Variable(f'{Domain} electrode {phase_name}hysteresis state') + h = pybamm.Variable(f'{Domain} electrode {phase_name}hysteresis state',domains={ + 'primary':f'{domain} electrode', + 'secondary':'current collector', + }) return {f'{Domain} electrode {phase_name}hysteresis state':h,} def get_coupled_variables(self, variables): domain, Domain = self.domain_Domain phase_name = self.phase_name + phase = self.phase if self.reaction == "lithium-ion main": T = variables[f"{Domain} electrode temperature [K]"] @@ -53,30 +57,60 @@ def get_coupled_variables(self, variables): T_bulk = pybamm.xyz_average(pybamm.size_average(T)) ocp_bulk_eq = self.phase_param.U(sto_bulk, T_bulk) - H = self.phase_param.H(sto_bulk) + c_s_rav = variables[ + f"R-averaged {domain} {phase_name}particle concentration distribution" + ] + # eps_s = variables[ + # f"{Domain} electrode {phase_name}active material volume fraction" + # ] + # eps_s_av = pybamm.x_average(eps_s) + # c_s_vol_av = pybamm.x_average(eps_s * c_s_rav) / eps_s_av + # c_s_vol = eps_s * c_s_rav + c_scale = self.phase_param.c_max + # L = self.domain_param.L + # A = self.param.A_cc + sto_rav = c_s_rav / c_scale + sto_rav = variables[f'R-averaged {domain} particle stoichiometry distribution'] + # sto_xav = variables[f'X-averaged {domain} particle stoichiometry distribution'] + # eps_s = pybamm.PrimaryBroadcast(eps_s,[f'{domain} particle size']) + + #! don't know how to broadcast this + variables[f"Total lithium in {phase} phase in {domain} electrode [mol]"] = sto_bulk* c_scale #c_s_vol * L * A + + + H = self.phase_param.H(sto_rav) variables[f'{Domain} electrode {phase_name}equilibrium OCP [V]'] = ocp_surf_eq variables[f'{Domain} electrode {phase_name}bulk equilibrium OCP [V]'] = ocp_bulk_eq - variables[f'{Domain} electrode {phase_name} OCP hysteresis [V]'] = H + variables[f'{Domain} electrode {phase_name}OCP hysteresis [V]'] = H # dQdU = variables[f'{Domain} electrode {phase_name}differential capacity [A.s.V-1]'] dU = pybamm.source(1,ocp_bulk_eq.diff(sto_bulk)) - Q = self.phase_param.Q(sto_bulk) + # dU = pybamm.PrimaryBroadcast(dU,[f'{domain} electrode']) + # dU = pybamm.PrimaryBroadcast(dU,[f'{domain} particle size']) + # dU = pybamm.FullBroadcast(dU,broadcast_domains={'primary':f'{domain} particle size', 'secondary':f'{domain} electrode'}) + Q = variables[f"Total lithium in {phase} phase in {domain} electrode [mol]"] * pybamm.constants.F / 3600 + # Q = pybamm.PrimaryBroadcast(Q,f'{domain} electrode') dQ = Q.diff(sto_bulk) dQdU = dQ/dU variables[f'{Domain} electrode {phase_name}differential capacity [A.s.V-1]'] = dQdU - ocp_surf = ocp_surf_eq + H * h - ocp_bulk = ocp_bulk_eq + H * h + variables[f'{Domain} electrode {phase_name}hysteresis state distribution'] = h + # H = pybamm.PrimaryBroadcast(H,f'{domain} particle size') + # h = pybamm.SecondaryBroadcast(h,f'current collector') + # ocp_surf_eq = pybamm.SecondaryBroadcast(ocp_surf_eq,[f'{domain} electrode']) + # ocp_bulk_eq = pybamm.PrimaryBroadcast(ocp_bulk_eq,[f'{domain} electrode']) + # ocp_bulk_eq = pybamm.PrimaryBroadcast(ocp_bulk_eq, [f'{domain} particle size']) + #! why is ocp surf not in electrode domain? why no x dimension? + H_x_av = pybamm.x_average(H) + h_x_av = pybamm.x_average(h) + ocp_surf = ocp_surf_eq + H_x_av * h_x_av + H_s_av = pybamm.size_average(H_x_av) + h_s_av = pybamm.size_average(h_x_av) + + ocp_bulk = ocp_bulk_eq + H_s_av * h_s_av variables.update(self._get_standard_ocp_variables(ocp_surf, ocp_bulk, dUdT)) return variables - # def set_algebraic(self, variables): - # domain, Domain = self.domain_Domain - # phase_name = self.phase_name - # dQdU = variables[f'{Domain} electrode {phase_name}differential capacity [A.s.V-1]'] - - # return super().set_algebraic(variables) - def set_rhs(self, variables): domain, Domain = self.domain_Domain phase_name = self.phase_name @@ -87,16 +121,15 @@ def set_rhs(self, variables): dQdU = variables[f'{Domain} electrode {phase_name}differential capacity [A.s.V-1]'] K = self.phase_param.K K_x = self.phase_param.K_x - h = variables[f'{Domain} electrode {phase_name}hysteresis state'] + h = variables[f'{Domain} electrode {phase_name}hysteresis state distribution'] - dhdt = K * (current/(Q_cell*(dQdU**K_x)))*(1-pybamm.sign(current)*h) + dhdt = K * (current/(Q_cell*(dQdU**K_x)))*(1-pybamm.sign(current)*h) #! current is backwards for a halfcell self.rhs[h] = dhdt def set_initial_conditions(self, variables): domain, Domain = self.domain_Domain phase_name = self.phase_name - h = pybamm.Variable(f'{Domain} electrode {phase_name}hysteresis state') + h = variables[f'{Domain} electrode {phase_name}hysteresis state'] + h_av = variables[f'{Domain} electrode {phase_name}hysteresis state distribution'] + self.initial_conditions[h_av] = pybamm.Scalar(0) self.initial_conditions[h] = pybamm.Scalar(0) - - # def set_boundary_conditions(self, variables): - # self.boundary_conditions[] From 80a03d67be0817659851829ab4ec0a77acde78c5 Mon Sep 17 00:00:00 2001 From: Tanner Leo Date: Fri, 15 Dec 2023 21:21:49 -0800 Subject: [PATCH 05/43] now passes TestDFN unit test well posed --- .../open_circuit_potential/plett_ocp.py | 48 ++++++------------- 1 file changed, 15 insertions(+), 33 deletions(-) diff --git a/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py b/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py index f5d0ce490a..cf0b27cb82 100644 --- a/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py +++ b/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py @@ -9,10 +9,11 @@ class PlettOpenCircuitPotential(BaseOpenCircuitPotential): def get_fundamental_variables(self): domain, Domain = self.domain_Domain phase_name = self.phase_name - h = pybamm.Variable(f'{Domain} electrode {phase_name}hysteresis state',domains={ + h = pybamm.Variable(f'{Domain} electrode {phase_name}hysteresis state', + domains={ 'primary':f'{domain} electrode', - 'secondary':'current collector', - }) + 'secondary':'current collector',} + ) return {f'{Domain} electrode {phase_name}hysteresis state':h,} def get_coupled_variables(self, variables): @@ -57,52 +58,33 @@ def get_coupled_variables(self, variables): T_bulk = pybamm.xyz_average(pybamm.size_average(T)) ocp_bulk_eq = self.phase_param.U(sto_bulk, T_bulk) - c_s_rav = variables[ - f"R-averaged {domain} {phase_name}particle concentration distribution" - ] - # eps_s = variables[ - # f"{Domain} electrode {phase_name}active material volume fraction" - # ] - # eps_s_av = pybamm.x_average(eps_s) - # c_s_vol_av = pybamm.x_average(eps_s * c_s_rav) / eps_s_av - # c_s_vol = eps_s * c_s_rav + c_scale = self.phase_param.c_max - # L = self.domain_param.L - # A = self.param.A_cc - sto_rav = c_s_rav / c_scale - sto_rav = variables[f'R-averaged {domain} particle stoichiometry distribution'] - # sto_xav = variables[f'X-averaged {domain} particle stoichiometry distribution'] - # eps_s = pybamm.PrimaryBroadcast(eps_s,[f'{domain} particle size']) - - #! don't know how to broadcast this variables[f"Total lithium in {phase} phase in {domain} electrode [mol]"] = sto_bulk* c_scale #c_s_vol * L * A - - H = self.phase_param.H(sto_rav) + H = self.phase_param.H(sto_surf) variables[f'{Domain} electrode {phase_name}equilibrium OCP [V]'] = ocp_surf_eq variables[f'{Domain} electrode {phase_name}bulk equilibrium OCP [V]'] = ocp_bulk_eq variables[f'{Domain} electrode {phase_name}OCP hysteresis [V]'] = H - # dQdU = variables[f'{Domain} electrode {phase_name}differential capacity [A.s.V-1]'] - - dU = pybamm.source(1,ocp_bulk_eq.diff(sto_bulk)) - # dU = pybamm.PrimaryBroadcast(dU,[f'{domain} electrode']) - # dU = pybamm.PrimaryBroadcast(dU,[f'{domain} particle size']) - # dU = pybamm.FullBroadcast(dU,broadcast_domains={'primary':f'{domain} particle size', 'secondary':f'{domain} electrode'}) - Q = variables[f"Total lithium in {phase} phase in {domain} electrode [mol]"] * pybamm.constants.F / 3600 - # Q = pybamm.PrimaryBroadcast(Q,f'{domain} electrode') - dQ = Q.diff(sto_bulk) + + dU = self.phase_param.U(sto_surf,T_bulk).diff(sto_surf) + dQ = self.phase_param.Q(sto_surf).diff(sto_surf) dQdU = dQ/dU variables[f'{Domain} electrode {phase_name}differential capacity [A.s.V-1]'] = dQdU variables[f'{Domain} electrode {phase_name}hysteresis state distribution'] = h - # H = pybamm.PrimaryBroadcast(H,f'{domain} particle size') + # H = H.orphans[0] + # H = pybamm.SecondaryBroadcast(H,f'{domain} electrode') + # H = pybamm.TertiaryBroadcast(H,f'current collector') # h = pybamm.SecondaryBroadcast(h,f'current collector') # ocp_surf_eq = pybamm.SecondaryBroadcast(ocp_surf_eq,[f'{domain} electrode']) # ocp_bulk_eq = pybamm.PrimaryBroadcast(ocp_bulk_eq,[f'{domain} electrode']) # ocp_bulk_eq = pybamm.PrimaryBroadcast(ocp_bulk_eq, [f'{domain} particle size']) #! why is ocp surf not in electrode domain? why no x dimension? + # H = pybamm.PrimaryBroadcast(H.orphans[0],[f'current collector']) + # h = pybamm.PrimaryBroadcast(h,[f'{domain} electrode']) H_x_av = pybamm.x_average(H) h_x_av = pybamm.x_average(h) - ocp_surf = ocp_surf_eq + H_x_av * h_x_av + ocp_surf = ocp_surf_eq + H * h H_s_av = pybamm.size_average(H_x_av) h_s_av = pybamm.size_average(h_x_av) From 7d2026c03fdc0e726457c4727f9de7805f085742 Mon Sep 17 00:00:00 2001 From: Tanner Leo Date: Fri, 15 Dec 2023 21:22:32 -0800 Subject: [PATCH 06/43] now passes TestDFN unit test well posed --- .../open_circuit_potential/plett_ocp.py | 48 ++++++------------- 1 file changed, 15 insertions(+), 33 deletions(-) diff --git a/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py b/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py index f5d0ce490a..cf0b27cb82 100644 --- a/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py +++ b/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py @@ -9,10 +9,11 @@ class PlettOpenCircuitPotential(BaseOpenCircuitPotential): def get_fundamental_variables(self): domain, Domain = self.domain_Domain phase_name = self.phase_name - h = pybamm.Variable(f'{Domain} electrode {phase_name}hysteresis state',domains={ + h = pybamm.Variable(f'{Domain} electrode {phase_name}hysteresis state', + domains={ 'primary':f'{domain} electrode', - 'secondary':'current collector', - }) + 'secondary':'current collector',} + ) return {f'{Domain} electrode {phase_name}hysteresis state':h,} def get_coupled_variables(self, variables): @@ -57,52 +58,33 @@ def get_coupled_variables(self, variables): T_bulk = pybamm.xyz_average(pybamm.size_average(T)) ocp_bulk_eq = self.phase_param.U(sto_bulk, T_bulk) - c_s_rav = variables[ - f"R-averaged {domain} {phase_name}particle concentration distribution" - ] - # eps_s = variables[ - # f"{Domain} electrode {phase_name}active material volume fraction" - # ] - # eps_s_av = pybamm.x_average(eps_s) - # c_s_vol_av = pybamm.x_average(eps_s * c_s_rav) / eps_s_av - # c_s_vol = eps_s * c_s_rav + c_scale = self.phase_param.c_max - # L = self.domain_param.L - # A = self.param.A_cc - sto_rav = c_s_rav / c_scale - sto_rav = variables[f'R-averaged {domain} particle stoichiometry distribution'] - # sto_xav = variables[f'X-averaged {domain} particle stoichiometry distribution'] - # eps_s = pybamm.PrimaryBroadcast(eps_s,[f'{domain} particle size']) - - #! don't know how to broadcast this variables[f"Total lithium in {phase} phase in {domain} electrode [mol]"] = sto_bulk* c_scale #c_s_vol * L * A - - H = self.phase_param.H(sto_rav) + H = self.phase_param.H(sto_surf) variables[f'{Domain} electrode {phase_name}equilibrium OCP [V]'] = ocp_surf_eq variables[f'{Domain} electrode {phase_name}bulk equilibrium OCP [V]'] = ocp_bulk_eq variables[f'{Domain} electrode {phase_name}OCP hysteresis [V]'] = H - # dQdU = variables[f'{Domain} electrode {phase_name}differential capacity [A.s.V-1]'] - - dU = pybamm.source(1,ocp_bulk_eq.diff(sto_bulk)) - # dU = pybamm.PrimaryBroadcast(dU,[f'{domain} electrode']) - # dU = pybamm.PrimaryBroadcast(dU,[f'{domain} particle size']) - # dU = pybamm.FullBroadcast(dU,broadcast_domains={'primary':f'{domain} particle size', 'secondary':f'{domain} electrode'}) - Q = variables[f"Total lithium in {phase} phase in {domain} electrode [mol]"] * pybamm.constants.F / 3600 - # Q = pybamm.PrimaryBroadcast(Q,f'{domain} electrode') - dQ = Q.diff(sto_bulk) + + dU = self.phase_param.U(sto_surf,T_bulk).diff(sto_surf) + dQ = self.phase_param.Q(sto_surf).diff(sto_surf) dQdU = dQ/dU variables[f'{Domain} electrode {phase_name}differential capacity [A.s.V-1]'] = dQdU variables[f'{Domain} electrode {phase_name}hysteresis state distribution'] = h - # H = pybamm.PrimaryBroadcast(H,f'{domain} particle size') + # H = H.orphans[0] + # H = pybamm.SecondaryBroadcast(H,f'{domain} electrode') + # H = pybamm.TertiaryBroadcast(H,f'current collector') # h = pybamm.SecondaryBroadcast(h,f'current collector') # ocp_surf_eq = pybamm.SecondaryBroadcast(ocp_surf_eq,[f'{domain} electrode']) # ocp_bulk_eq = pybamm.PrimaryBroadcast(ocp_bulk_eq,[f'{domain} electrode']) # ocp_bulk_eq = pybamm.PrimaryBroadcast(ocp_bulk_eq, [f'{domain} particle size']) #! why is ocp surf not in electrode domain? why no x dimension? + # H = pybamm.PrimaryBroadcast(H.orphans[0],[f'current collector']) + # h = pybamm.PrimaryBroadcast(h,[f'{domain} electrode']) H_x_av = pybamm.x_average(H) h_x_av = pybamm.x_average(h) - ocp_surf = ocp_surf_eq + H_x_av * h_x_av + ocp_surf = ocp_surf_eq + H * h H_s_av = pybamm.size_average(H_x_av) h_s_av = pybamm.size_average(h_x_av) From 551b0235769b2333233df659b121b9492ce8f7bb Mon Sep 17 00:00:00 2001 From: Tanner Leo Date: Thu, 21 Dec 2023 13:31:39 -0800 Subject: [PATCH 07/43] passing MPM integration test --- .../interface/open_circuit_potential/plett_ocp.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py b/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py index cf0b27cb82..77ac8618ad 100644 --- a/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py +++ b/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py @@ -84,7 +84,8 @@ def get_coupled_variables(self, variables): # h = pybamm.PrimaryBroadcast(h,[f'{domain} electrode']) H_x_av = pybamm.x_average(H) h_x_av = pybamm.x_average(h) - ocp_surf = ocp_surf_eq + H * h + # variables[f'X-averaged {domain} electrode {phase_name}hysteresis state'] = h_x_av + ocp_surf = ocp_surf_eq + H_x_av * h_x_av H_s_av = pybamm.size_average(H_x_av) h_s_av = pybamm.size_average(h_x_av) @@ -98,12 +99,16 @@ def set_rhs(self, variables): phase_name = self.phase_name current = self.param.current_with_time - + current = variables[f"{Domain} electrode interfacial current density [A.m-2]"] + # current = current.orphans[0] + # current = current.SecondaryBroadcast(current,f'{domain} electrode') Q_cell = variables[f'{Domain} electrode capacity [A.h]'] dQdU = variables[f'{Domain} electrode {phase_name}differential capacity [A.s.V-1]'] + dQdU = dQdU.orphans[0] K = self.phase_param.K K_x = self.phase_param.K_x - h = variables[f'{Domain} electrode {phase_name}hysteresis state distribution'] + h = variables[f'{Domain} electrode {phase_name}hysteresis state'] + # h_x_av = variables[f'X-averaged {domain} electrode {phase_name}hysteresis state'] dhdt = K * (current/(Q_cell*(dQdU**K_x)))*(1-pybamm.sign(current)*h) #! current is backwards for a halfcell self.rhs[h] = dhdt @@ -112,6 +117,6 @@ def set_initial_conditions(self, variables): domain, Domain = self.domain_Domain phase_name = self.phase_name h = variables[f'{Domain} electrode {phase_name}hysteresis state'] - h_av = variables[f'{Domain} electrode {phase_name}hysteresis state distribution'] - self.initial_conditions[h_av] = pybamm.Scalar(0) + # h_av = variables[f'{Domain} electrode {phase_name}hysteresis state distribution'] + # self.initial_conditions[h_av] = pybamm.Scalar(0) self.initial_conditions[h] = pybamm.Scalar(0) From ab3f87de88b6dd79d4e4b15c23bd643c3536fe64 Mon Sep 17 00:00:00 2001 From: Tanner Leo Date: Thu, 21 Dec 2023 13:52:46 -0800 Subject: [PATCH 08/43] nearly passing MPM + DFN tests --- .../interface/open_circuit_potential/plett_ocp.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py b/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py index 77ac8618ad..a9e58ec0c1 100644 --- a/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py +++ b/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py @@ -84,8 +84,13 @@ def get_coupled_variables(self, variables): # h = pybamm.PrimaryBroadcast(h,[f'{domain} electrode']) H_x_av = pybamm.x_average(H) h_x_av = pybamm.x_average(h) - # variables[f'X-averaged {domain} electrode {phase_name}hysteresis state'] = h_x_av - ocp_surf = ocp_surf_eq + H_x_av * h_x_av + if domain_options["particle size"] == "distribution": + if sto_surf.domains['primary'] == f"{domain} electrode": + ocp_surf = ocp_surf_eq + H * h + else: + ocp_surf = ocp_surf_eq + H_x_av * h_x_av + else: + ocp_surf = ocp_surf_eq + H * h H_s_av = pybamm.size_average(H_x_av) h_s_av = pybamm.size_average(h_x_av) From 9388adfbab4cc5ffe77321bc874783574417bbf9 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 5 Apr 2024 01:28:48 +0000 Subject: [PATCH 09/43] style: pre-commit fixes --- .../lithium_ion/base_lithium_ion_model.py | 2 +- .../open_circuit_potential/plett_ocp.py | 63 ++++++++++++------- pybamm/parameters/lithium_ion_parameters.py | 9 +-- .../test_lithium_ion/test_mpm.py | 9 +-- 4 files changed, 51 insertions(+), 32 deletions(-) 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 7c940b21b8..b7462fbe94 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 @@ -249,7 +249,7 @@ def set_open_circuit_potential_submodel(self): elif ocp_option == "current sigmoid": ocp_model = ocp_submodels.CurrentSigmoidOpenCircuitPotential elif ocp_option == "Plett": - pybamm.citations.register('Wycisk2022') + pybamm.citations.register("Wycisk2022") ocp_model = ocp_submodels.PlettOpenCircuitPotential elif ocp_option == "MSMR": ocp_model = ocp_submodels.MSMROpenCircuitPotential diff --git a/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py b/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py index a9e58ec0c1..f65fb2e585 100644 --- a/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py +++ b/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py @@ -9,12 +9,16 @@ class PlettOpenCircuitPotential(BaseOpenCircuitPotential): def get_fundamental_variables(self): domain, Domain = self.domain_Domain phase_name = self.phase_name - h = pybamm.Variable(f'{Domain} electrode {phase_name}hysteresis state', - domains={ - 'primary':f'{domain} electrode', - 'secondary':'current collector',} + h = pybamm.Variable( + f"{Domain} electrode {phase_name}hysteresis state", + domains={ + "primary": f"{domain} electrode", + "secondary": "current collector", + }, ) - return {f'{Domain} electrode {phase_name}hysteresis state':h,} + return { + f"{Domain} electrode {phase_name}hysteresis state": h, + } def get_coupled_variables(self, variables): domain, Domain = self.domain_Domain @@ -23,7 +27,7 @@ def get_coupled_variables(self, variables): if self.reaction == "lithium-ion main": T = variables[f"{Domain} electrode temperature [K]"] - h = variables[f'{Domain} electrode {phase_name}hysteresis state'] + h = variables[f"{Domain} electrode {phase_name}hysteresis state"] # For "particle-size distribution" models, take distribution version # of c_s_surf that depends on particle size. domain_options = getattr(self.options, domain) @@ -38,7 +42,7 @@ def get_coupled_variables(self, variables): sto_surf = sto_surf.orphans[0] T = T.orphans[0] T = pybamm.PrimaryBroadcast(T, [f"{domain} particle size"]) - h = pybamm.PrimaryBroadcast(h, [f'{domain} particle size']) + h = pybamm.PrimaryBroadcast(h, [f"{domain} particle size"]) else: sto_surf = variables[ f"{Domain} {phase_name}particle surface stoichiometry" @@ -58,20 +62,29 @@ def get_coupled_variables(self, variables): T_bulk = pybamm.xyz_average(pybamm.size_average(T)) ocp_bulk_eq = self.phase_param.U(sto_bulk, T_bulk) - c_scale = self.phase_param.c_max - variables[f"Total lithium in {phase} phase in {domain} electrode [mol]"] = sto_bulk* c_scale #c_s_vol * L * A + variables[f"Total lithium in {phase} phase in {domain} electrode [mol]"] = ( + sto_bulk * c_scale + ) # c_s_vol * L * A H = self.phase_param.H(sto_surf) - variables[f'{Domain} electrode {phase_name}equilibrium OCP [V]'] = ocp_surf_eq - variables[f'{Domain} electrode {phase_name}bulk equilibrium OCP [V]'] = ocp_bulk_eq - variables[f'{Domain} electrode {phase_name}OCP hysteresis [V]'] = H - - dU = self.phase_param.U(sto_surf,T_bulk).diff(sto_surf) + variables[f"{Domain} electrode {phase_name}equilibrium OCP [V]"] = ( + ocp_surf_eq + ) + variables[f"{Domain} electrode {phase_name}bulk equilibrium OCP [V]"] = ( + ocp_bulk_eq + ) + variables[f"{Domain} electrode {phase_name}OCP hysteresis [V]"] = H + + dU = self.phase_param.U(sto_surf, T_bulk).diff(sto_surf) dQ = self.phase_param.Q(sto_surf).diff(sto_surf) - dQdU = dQ/dU - variables[f'{Domain} electrode {phase_name}differential capacity [A.s.V-1]'] = dQdU - variables[f'{Domain} electrode {phase_name}hysteresis state distribution'] = h + dQdU = dQ / dU + variables[ + f"{Domain} electrode {phase_name}differential capacity [A.s.V-1]" + ] = dQdU + variables[ + f"{Domain} electrode {phase_name}hysteresis state distribution" + ] = h # H = H.orphans[0] # H = pybamm.SecondaryBroadcast(H,f'{domain} electrode') # H = pybamm.TertiaryBroadcast(H,f'current collector') @@ -85,7 +98,7 @@ def get_coupled_variables(self, variables): H_x_av = pybamm.x_average(H) h_x_av = pybamm.x_average(h) if domain_options["particle size"] == "distribution": - if sto_surf.domains['primary'] == f"{domain} electrode": + if sto_surf.domains["primary"] == f"{domain} electrode": ocp_surf = ocp_surf_eq + H * h else: ocp_surf = ocp_surf_eq + H_x_av * h_x_av @@ -107,21 +120,25 @@ def set_rhs(self, variables): current = variables[f"{Domain} electrode interfacial current density [A.m-2]"] # current = current.orphans[0] # current = current.SecondaryBroadcast(current,f'{domain} electrode') - Q_cell = variables[f'{Domain} electrode capacity [A.h]'] - dQdU = variables[f'{Domain} electrode {phase_name}differential capacity [A.s.V-1]'] + Q_cell = variables[f"{Domain} electrode capacity [A.h]"] + dQdU = variables[ + f"{Domain} electrode {phase_name}differential capacity [A.s.V-1]" + ] dQdU = dQdU.orphans[0] K = self.phase_param.K K_x = self.phase_param.K_x - h = variables[f'{Domain} electrode {phase_name}hysteresis state'] + h = variables[f"{Domain} electrode {phase_name}hysteresis state"] # h_x_av = variables[f'X-averaged {domain} electrode {phase_name}hysteresis state'] - dhdt = K * (current/(Q_cell*(dQdU**K_x)))*(1-pybamm.sign(current)*h) #! current is backwards for a halfcell + dhdt = ( + K * (current / (Q_cell * (dQdU**K_x))) * (1 - pybamm.sign(current) * h) + ) #! current is backwards for a halfcell self.rhs[h] = dhdt def set_initial_conditions(self, variables): domain, Domain = self.domain_Domain phase_name = self.phase_name - h = variables[f'{Domain} electrode {phase_name}hysteresis state'] + h = variables[f"{Domain} electrode {phase_name}hysteresis state"] # h_av = variables[f'{Domain} electrode {phase_name}hysteresis state distribution'] # self.initial_conditions[h_av] = pybamm.Scalar(0) self.initial_conditions[h] = pybamm.Scalar(0) diff --git a/pybamm/parameters/lithium_ion_parameters.py b/pybamm/parameters/lithium_ion_parameters.py index 17ff57e77d..6682ad59e8 100644 --- a/pybamm/parameters/lithium_ion_parameters.py +++ b/pybamm/parameters/lithium_ion_parameters.py @@ -536,8 +536,10 @@ def _set_parameters(self): self.epsilon_s * pybamm.r_average(self.c_init) ) # if self.options['open-circuit potential'] == 'Plett': - self.K = pybamm.Parameter(f'{pref}{Domain} particle hysteresis decay rate') - self.K_x = pybamm.Parameter(f'{pref}{Domain} particle hysteresis switching factor') + self.K = pybamm.Parameter(f"{pref}{Domain} particle hysteresis decay rate") + self.K_x = pybamm.Parameter( + f"{pref}{Domain} particle hysteresis switching factor" + ) self.h_init = pybamm.Scalar(0) if self.options["open-circuit potential"] != "MSMR": @@ -649,12 +651,11 @@ def Q(self, sto): """Capacity change as a function of stoichiometry""" c_max = self.c_max epsilon_s_av = self.epsilon_s_av - V_electrode = self.main_param.A_cc*self.domain_param.L + V_electrode = self.main_param.A_cc * self.domain_param.L Li_max = c_max * V_electrode * epsilon_s_av Q_max = Li_max * self.main_param.F / 3600 return Q_max * sto - def dUdT(self, sto): """ Dimensional entropic change of the open-circuit potential [V.K-1] diff --git a/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_mpm.py b/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_mpm.py index 2706d6035c..a1d4b4a7b6 100644 --- a/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_mpm.py +++ b/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_mpm.py @@ -75,11 +75,12 @@ def test_plett_ocp(self): parameter_values = pybamm.get_size_distribution_parameters(parameter_values) parameter_values.update( { - "Negative electrode OCP [V]" - "": parameter_values["Negative electrode OCP [V]"], + "Negative electrode OCP [V]" "": parameter_values[ + "Negative electrode OCP [V]" + ], "Negative particle hysteresis decay rate": 1, - "Negative particle hysteresis switching factor":1, - "Negative electrode OCP hysteresis [V]":lambda sto: 1, + "Negative particle hysteresis switching factor": 1, + "Negative electrode OCP hysteresis [V]": lambda sto: 1, }, check_already_exists=False, ) From 7d4aa192daee22b2519c98819ef15fd97096dd2f Mon Sep 17 00:00:00 2001 From: Tanner Leo Date: Tue, 16 Apr 2024 17:48:02 -0700 Subject: [PATCH 10/43] add citations --- pybamm/CITATIONS.bib | 2 +- .../submodels/interface/open_circuit_potential/plett_ocp.py | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/pybamm/CITATIONS.bib b/pybamm/CITATIONS.bib index 33afa57f28..d19093a323 100644 --- a/pybamm/CITATIONS.bib +++ b/pybamm/CITATIONS.bib @@ -692,7 +692,7 @@ @article{landesfeind2019temperature publisher={The Electrochemical Society} } -@article{WYCISK2022105016, +@article{Wycisk2022, title = {Modified Plett-model for modeling voltage hysteresis in lithium-ion cells}, journal = {Journal of Energy Storage}, volume = {52}, diff --git a/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py b/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py index f65fb2e585..32bab5af8c 100644 --- a/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py +++ b/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py @@ -6,6 +6,11 @@ class PlettOpenCircuitPotential(BaseOpenCircuitPotential): + + def __init__(self, param, domain, reaction, options, phase="primary"): + super().__init__(param, domain, reaction, options=options, phase=phase) + pybamm.citations.register("Wycisk2022") + def get_fundamental_variables(self): domain, Domain = self.domain_Domain phase_name = self.phase_name From 2463e2ae84489d3ce4c387c0425aef71ac42adaa Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 17 Apr 2024 00:48:21 +0000 Subject: [PATCH 11/43] style: pre-commit fixes --- .../submodels/interface/open_circuit_potential/plett_ocp.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py b/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py index 32bab5af8c..50d12e7ae9 100644 --- a/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py +++ b/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py @@ -6,7 +6,6 @@ class PlettOpenCircuitPotential(BaseOpenCircuitPotential): - def __init__(self, param, domain, reaction, options, phase="primary"): super().__init__(param, domain, reaction, options=options, phase=phase) pybamm.citations.register("Wycisk2022") From 1bcb524ff8caaeb7c77304843ea3953a71af1309 Mon Sep 17 00:00:00 2001 From: Tanner Leo Date: Tue, 16 Apr 2024 18:17:37 -0700 Subject: [PATCH 12/43] remove unessesary citation --- .../submodels/interface/open_circuit_potential/plett_ocp.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py b/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py index 50d12e7ae9..f65fb2e585 100644 --- a/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py +++ b/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py @@ -6,10 +6,6 @@ class PlettOpenCircuitPotential(BaseOpenCircuitPotential): - def __init__(self, param, domain, reaction, options, phase="primary"): - super().__init__(param, domain, reaction, options=options, phase=phase) - pybamm.citations.register("Wycisk2022") - def get_fundamental_variables(self): domain, Domain = self.domain_Domain phase_name = self.phase_name From 3e89fb4ea70562258a00d6aa8b4e4d484da32345 Mon Sep 17 00:00:00 2001 From: Tanner Leo Date: Tue, 16 Apr 2024 18:37:15 -0700 Subject: [PATCH 13/43] passes all unit tests --- .../interface/open_circuit_potential/plett_ocp.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py b/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py index f65fb2e585..6d858fef47 100644 --- a/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py +++ b/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py @@ -98,8 +98,15 @@ def get_coupled_variables(self, variables): H_x_av = pybamm.x_average(H) h_x_av = pybamm.x_average(h) if domain_options["particle size"] == "distribution": - if sto_surf.domains["primary"] == f"{domain} electrode": + if f"{domain} electrode" in sto_surf.domains["primary"]: ocp_surf = ocp_surf_eq + H * h + elif f"{domain} particle size" in sto_surf.domains["primary"]: + # check if MPM Model + if 'current collector' in sto_surf.domains["secondary"]: + ocp_surf = ocp_surf_eq + H_x_av * h_x_av + # must be DFN with PSD model + else: + ocp_surf = ocp_surf_eq + H * h else: ocp_surf = ocp_surf_eq + H_x_av * h_x_av else: From 27e075fd9c46ad163588cd92f3035e3d149d0c71 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 17 Apr 2024 01:37:27 +0000 Subject: [PATCH 14/43] style: pre-commit fixes --- .../submodels/interface/open_circuit_potential/plett_ocp.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py b/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py index 6d858fef47..ce8bf73b37 100644 --- a/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py +++ b/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py @@ -102,7 +102,7 @@ def get_coupled_variables(self, variables): ocp_surf = ocp_surf_eq + H * h elif f"{domain} particle size" in sto_surf.domains["primary"]: # check if MPM Model - if 'current collector' in sto_surf.domains["secondary"]: + if "current collector" in sto_surf.domains["secondary"]: ocp_surf = ocp_surf_eq + H_x_av * h_x_av # must be DFN with PSD model else: From 2e7d81b9a972d88f9051f0a48984398318760823 Mon Sep 17 00:00:00 2001 From: Tanner Leo Date: Tue, 16 Apr 2024 18:57:18 -0700 Subject: [PATCH 15/43] move Q from lithium ion function to submodel coupled variable --- .../open_circuit_potential/plett_ocp.py | 21 +++++++++---------- pybamm/parameters/lithium_ion_parameters.py | 9 -------- 2 files changed, 10 insertions(+), 20 deletions(-) diff --git a/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py b/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py index 6d858fef47..a5038a4f17 100644 --- a/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py +++ b/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py @@ -25,6 +25,14 @@ def get_coupled_variables(self, variables): phase_name = self.phase_name phase = self.phase + # get dQ, change in capacity with respect to stoichiometry + c_max = self.phase_param.c_max + epsilon_s_av = self.phase_param.epsilon_s_av + V_electrode = self.param.A_cc * self.domain_param.L + Li_max = c_max * V_electrode * epsilon_s_av + Q_max = Li_max * self.param.F / 3600 + dQ = Q_max + if self.reaction == "lithium-ion main": T = variables[f"{Domain} electrode temperature [K]"] h = variables[f"{Domain} electrode {phase_name}hysteresis state"] @@ -77,7 +85,7 @@ def get_coupled_variables(self, variables): variables[f"{Domain} electrode {phase_name}OCP hysteresis [V]"] = H dU = self.phase_param.U(sto_surf, T_bulk).diff(sto_surf) - dQ = self.phase_param.Q(sto_surf).diff(sto_surf) + # dQ = self.phase_param.Q(sto_surf).diff(sto_surf) dQdU = dQ / dU variables[ f"{Domain} electrode {phase_name}differential capacity [A.s.V-1]" @@ -85,18 +93,9 @@ def get_coupled_variables(self, variables): variables[ f"{Domain} electrode {phase_name}hysteresis state distribution" ] = h - # H = H.orphans[0] - # H = pybamm.SecondaryBroadcast(H,f'{domain} electrode') - # H = pybamm.TertiaryBroadcast(H,f'current collector') - # h = pybamm.SecondaryBroadcast(h,f'current collector') - # ocp_surf_eq = pybamm.SecondaryBroadcast(ocp_surf_eq,[f'{domain} electrode']) - # ocp_bulk_eq = pybamm.PrimaryBroadcast(ocp_bulk_eq,[f'{domain} electrode']) - # ocp_bulk_eq = pybamm.PrimaryBroadcast(ocp_bulk_eq, [f'{domain} particle size']) - #! why is ocp surf not in electrode domain? why no x dimension? - # H = pybamm.PrimaryBroadcast(H.orphans[0],[f'current collector']) - # h = pybamm.PrimaryBroadcast(h,[f'{domain} electrode']) H_x_av = pybamm.x_average(H) h_x_av = pybamm.x_average(h) + # check if psd if domain_options["particle size"] == "distribution": if f"{domain} electrode" in sto_surf.domains["primary"]: ocp_surf = ocp_surf_eq + H * h diff --git a/pybamm/parameters/lithium_ion_parameters.py b/pybamm/parameters/lithium_ion_parameters.py index 6682ad59e8..b7cc564277 100644 --- a/pybamm/parameters/lithium_ion_parameters.py +++ b/pybamm/parameters/lithium_ion_parameters.py @@ -647,15 +647,6 @@ def H(self, sto): ) return h_ref - def Q(self, sto): - """Capacity change as a function of stoichiometry""" - c_max = self.c_max - epsilon_s_av = self.epsilon_s_av - V_electrode = self.main_param.A_cc * self.domain_param.L - Li_max = c_max * V_electrode * epsilon_s_av - Q_max = Li_max * self.main_param.F / 3600 - return Q_max * sto - def dUdT(self, sto): """ Dimensional entropic change of the open-circuit potential [V.K-1] From e2fa1ed5777ae4002bd6b53d51ace506d1c02416 Mon Sep 17 00:00:00 2001 From: Tanner Leo Date: Tue, 16 Apr 2024 19:11:13 -0700 Subject: [PATCH 16/43] clean up changes --- .../open_circuit_potential/plett_ocp.py | 17 +++++++---------- pybamm/parameters/lithium_ion_parameters.py | 2 -- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py b/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py index c98f439978..5073bc5914 100644 --- a/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py +++ b/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py @@ -97,17 +97,19 @@ def get_coupled_variables(self, variables): h_x_av = pybamm.x_average(h) # check if psd if domain_options["particle size"] == "distribution": - if f"{domain} electrode" in sto_surf.domains["primary"]: - ocp_surf = ocp_surf_eq + H * h - elif f"{domain} particle size" in sto_surf.domains["primary"]: + # should always be true + if f"{domain} particle size" in sto_surf.domains["primary"]: # check if MPM Model if "current collector" in sto_surf.domains["secondary"]: ocp_surf = ocp_surf_eq + H_x_av * h_x_av # must be DFN with PSD model - else: + elif f'{domain} electrode' in sto_surf.domains['secondary']: ocp_surf = ocp_surf_eq + H * h + else: + raise ValueError('Model type not implementted with open-circuit potential as "Plett"') else: - ocp_surf = ocp_surf_eq + H_x_av * h_x_av + raise ValueError('Model type not implementted with open-circuit potential as "Plett"') + # must not be a psd else: ocp_surf = ocp_surf_eq + H * h H_s_av = pybamm.size_average(H_x_av) @@ -124,8 +126,6 @@ def set_rhs(self, variables): current = self.param.current_with_time current = variables[f"{Domain} electrode interfacial current density [A.m-2]"] - # current = current.orphans[0] - # current = current.SecondaryBroadcast(current,f'{domain} electrode') Q_cell = variables[f"{Domain} electrode capacity [A.h]"] dQdU = variables[ f"{Domain} electrode {phase_name}differential capacity [A.s.V-1]" @@ -134,7 +134,6 @@ def set_rhs(self, variables): K = self.phase_param.K K_x = self.phase_param.K_x h = variables[f"{Domain} electrode {phase_name}hysteresis state"] - # h_x_av = variables[f'X-averaged {domain} electrode {phase_name}hysteresis state'] dhdt = ( K * (current / (Q_cell * (dQdU**K_x))) * (1 - pybamm.sign(current) * h) @@ -145,6 +144,4 @@ def set_initial_conditions(self, variables): domain, Domain = self.domain_Domain phase_name = self.phase_name h = variables[f"{Domain} electrode {phase_name}hysteresis state"] - # h_av = variables[f'{Domain} electrode {phase_name}hysteresis state distribution'] - # self.initial_conditions[h_av] = pybamm.Scalar(0) self.initial_conditions[h] = pybamm.Scalar(0) diff --git a/pybamm/parameters/lithium_ion_parameters.py b/pybamm/parameters/lithium_ion_parameters.py index b7cc564277..29da62e4de 100644 --- a/pybamm/parameters/lithium_ion_parameters.py +++ b/pybamm/parameters/lithium_ion_parameters.py @@ -662,8 +662,6 @@ def dUdT(self, sto): inputs, ) - # def dQdU(self,sto) - def X_j(self, index): "Available host sites indexed by reaction j" domain = self.domain From 9b0a4aa34e5187d905c8d04767002f7cc90234c9 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 17 Apr 2024 02:11:24 +0000 Subject: [PATCH 17/43] style: pre-commit fixes --- .../interface/open_circuit_potential/plett_ocp.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py b/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py index 5073bc5914..253df8bcea 100644 --- a/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py +++ b/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py @@ -103,12 +103,16 @@ def get_coupled_variables(self, variables): if "current collector" in sto_surf.domains["secondary"]: ocp_surf = ocp_surf_eq + H_x_av * h_x_av # must be DFN with PSD model - elif f'{domain} electrode' in sto_surf.domains['secondary']: + elif f"{domain} electrode" in sto_surf.domains["secondary"]: ocp_surf = ocp_surf_eq + H * h else: - raise ValueError('Model type not implementted with open-circuit potential as "Plett"') + raise ValueError( + 'Model type not implementted with open-circuit potential as "Plett"' + ) else: - raise ValueError('Model type not implementted with open-circuit potential as "Plett"') + raise ValueError( + 'Model type not implementted with open-circuit potential as "Plett"' + ) # must not be a psd else: ocp_surf = ocp_surf_eq + H * h From 2ed9dea57e2a9587ea3a6751b2332c009f412e67 Mon Sep 17 00:00:00 2001 From: Tanner Leo Date: Wed, 17 Apr 2024 17:26:28 -0700 Subject: [PATCH 18/43] working example notebook and temporary revert to dQ as a function --- .../examples/notebooks/models/DCHS.ipynb | 221 ++++++++++++++++++ .../open_circuit_potential/plett_ocp.py | 20 +- pybamm/parameters/lithium_ion_parameters.py | 9 + 3 files changed, 241 insertions(+), 9 deletions(-) create mode 100644 docs/source/examples/notebooks/models/DCHS.ipynb diff --git a/docs/source/examples/notebooks/models/DCHS.ipynb b/docs/source/examples/notebooks/models/DCHS.ipynb new file mode 100644 index 0000000000..ed9cb8ae4d --- /dev/null +++ b/docs/source/examples/notebooks/models/DCHS.ipynb @@ -0,0 +1,221 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import pybamm\n", + "import numpy as np\n", + "\n", + "parameters = pybamm.ParameterValues(\"Chen2020_composite\")\n", + "\n", + "\n", + "# get the lithiation and delithiation functions\n", + "\n", + "lithiation = parameters['Secondary: Negative electrode lithiation OCP [V]']\n", + "delithiation = parameters['Secondary: Negative electrode delithiation OCP [V]']\n", + "\n", + "# define the new OCP function\n", + "def ocp(sto):\n", + " return (lithiation(sto) + delithiation(sto))/2\n", + "\n", + "# define hysteresis function\n", + "def hysteresis(sto):\n", + " return (lithiation(sto) - delithiation(sto))/-2\n", + "\n", + "# add additional parameters\n", + "parameters.update({\n", + " 'Secondary: Negative electrode OCP [V]': ocp,\n", + " 'Secondary: Negative particle hysteresis decay rate': 0.1,\n", + " 'Secondary: Negative electrode OCP hysteresis [V]': hysteresis,\n", + " 'Secondary: Negative particle hysteresis switching factor': 1\n", + "\n", + "},check_already_exists=False)\n", + "\n", + "model = pybamm.lithium_ion.SPM({'open-circuit potential':(('single','Plett'),'single'),'particle phases':('2','1')})\n", + "\n", + "\n", + "\n", + "experiment = pybamm.Experiment([(\"Discharge at 1 C for 1 hour or until 2.5 V\",\"Rest for 15 minutes\"),(\"Charge at 1C until 4.2 V\",\"Hold at 4.2 V until 50 mA\",\"Rest for 15 minutes\")])\n", + "\n", + "\n", + "simulation = pybamm.Simulation(model, experiment=experiment, parameter_values=parameters)\n", + "solution = simulation.solve(calc_esoh=False)" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "4656f55659574e728171f99ce8037aab", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "interactive(children=(FloatSlider(value=0.0, description='t', max=3.3439065949597495, step=0.03343906594959749…" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "solution.plot([\n", + " \"X-averaged negative electrode secondary hysteresis state\",\n", + " \"Negative electrode secondary hysteresis state\",\n", + " 'Negative electrode secondary open-circuit potential [V]',\n", + " 'Terminal voltage [V]',\n", + " 'X-averaged negative electrode secondary open-circuit potential [V]'\n", + "])" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "import pybamm\n", + "import numpy as np\n", + "\n", + "parameters = pybamm.ParameterValues(\"Chen2020_composite\")\n", + "\n", + "\n", + "# get the lithiation and delithiation functions\n", + "\n", + "lithiation = parameters['Secondary: Negative electrode lithiation OCP [V]']\n", + "delithiation = parameters['Secondary: Negative electrode delithiation OCP [V]']\n", + "\n", + "# define the new OCP function\n", + "def ocp(sto):\n", + " return (lithiation(sto) + delithiation(sto))/2\n", + "\n", + "# define hysteresis function\n", + "def hysteresis(sto):\n", + " return (lithiation(sto) - delithiation(sto))/-2\n", + "\n", + "# add additional parameters\n", + "parameters.update({\n", + " 'Secondary: Negative electrode OCP [V]': ocp,\n", + " 'Secondary: Negative particle hysteresis decay rate': 0.1,\n", + " 'Secondary: Negative electrode OCP hysteresis [V]': hysteresis,\n", + " 'Secondary: Negative particle hysteresis switching factor': 1\n", + "\n", + "},check_already_exists=False)\n", + "\n", + "model = pybamm.lithium_ion.SPM({'open-circuit potential':(('single','current sigmoid'),'single'),'particle phases':('2','1')})\n", + "\n", + "\n", + "\n", + "experiment = pybamm.Experiment([(\"Discharge at 1 C for 1 hour or until 2.5 V\",\"Rest for 15 minutes\"),(\"Charge at 1C until 4.2 V\",\"Hold at 4.2 V until 50 mA\",\"Rest for 15 minutes\")])\n", + "\n", + "\n", + "simulation = pybamm.Simulation(model, experiment=experiment, parameter_values=parameters)\n", + "solution_sigmoid = simulation.solve(calc_esoh=False)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "f1fe970ea9b94028a98720a87eb8daf2", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "interactive(children=(FloatSlider(value=0.0, description='t', max=3.3455896030671757, step=0.03345589603067175…" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "solution_sigmoid.plot([\n", + " # \"X-averaged negative electrode secondary hysteresis state\",\n", + " # \"Negative electrode secondary hysteresis state\",\n", + " 'Negative electrode secondary open-circuit potential [V]',\n", + " 'Terminal voltage [V]',\n", + " 'X-averaged negative electrode secondary open-circuit potential [V]'\n", + "])" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "38c1d5584ef94e30b3711fa1a78a5a3c", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "interactive(children=(FloatSlider(value=0.0, description='t', max=3.3455896030671757, step=0.03345589603067175…" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "pybamm.QuickPlot([solution, solution_sigmoid], labels=[\"Plett\", \"Sigmoid\"],output_variables=['Negative electrode secondary open-circuit potential [V]',\n", + " 'Terminal voltage [V]',\n", + " 'X-averaged negative electrode secondary open-circuit potential [V]']).dynamic_plot()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "venv", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.0" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py b/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py index 253df8bcea..3c48186aff 100644 --- a/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py +++ b/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py @@ -25,13 +25,6 @@ def get_coupled_variables(self, variables): phase_name = self.phase_name phase = self.phase - # get dQ, change in capacity with respect to stoichiometry - c_max = self.phase_param.c_max - epsilon_s_av = self.phase_param.epsilon_s_av - V_electrode = self.param.A_cc * self.domain_param.L - Li_max = c_max * V_electrode * epsilon_s_av - Q_max = Li_max * self.param.F / 3600 - dQ = Q_max if self.reaction == "lithium-ion main": T = variables[f"{Domain} electrode temperature [K]"] @@ -70,6 +63,14 @@ def get_coupled_variables(self, variables): T_bulk = pybamm.xyz_average(pybamm.size_average(T)) ocp_bulk_eq = self.phase_param.U(sto_bulk, T_bulk) + # # get dQ, change in capacity with respect to stoichiometry + # c_max = self.phase_param.c_max + # epsilon_s_av = self.phase_param.epsilon_s_av + # V_electrode = self.param.A_cc * self.domain_param.L + # Li_max = c_max * V_electrode * epsilon_s_av + # Q_max = Li_max * self.param.F / 3600 + # dQ = Q_max * sto_bulk + c_scale = self.phase_param.c_max variables[f"Total lithium in {phase} phase in {domain} electrode [mol]"] = ( sto_bulk * c_scale @@ -85,7 +86,7 @@ def get_coupled_variables(self, variables): variables[f"{Domain} electrode {phase_name}OCP hysteresis [V]"] = H dU = self.phase_param.U(sto_surf, T_bulk).diff(sto_surf) - # dQ = self.phase_param.Q(sto_surf).diff(sto_surf) + dQ = self.phase_param.Q(sto_surf).diff(sto_surf) dQdU = dQ / dU variables[ f"{Domain} electrode {phase_name}differential capacity [A.s.V-1]" @@ -95,6 +96,7 @@ def get_coupled_variables(self, variables): ] = h H_x_av = pybamm.x_average(H) h_x_av = pybamm.x_average(h) + variables[f'X-averaged {domain} electrode {phase_name}hysteresis state'] = h_x_av # check if psd if domain_options["particle size"] == "distribution": # should always be true @@ -129,7 +131,7 @@ def set_rhs(self, variables): phase_name = self.phase_name current = self.param.current_with_time - current = variables[f"{Domain} electrode interfacial current density [A.m-2]"] + current = variables[f"{Domain} electrode {phase_name}interfacial current density [A.m-2]"] Q_cell = variables[f"{Domain} electrode capacity [A.h]"] dQdU = variables[ f"{Domain} electrode {phase_name}differential capacity [A.s.V-1]" diff --git a/pybamm/parameters/lithium_ion_parameters.py b/pybamm/parameters/lithium_ion_parameters.py index 29da62e4de..588bbe09b7 100644 --- a/pybamm/parameters/lithium_ion_parameters.py +++ b/pybamm/parameters/lithium_ion_parameters.py @@ -647,6 +647,15 @@ def H(self, sto): ) return h_ref + def Q(self, sto): + """Capacity change as a function of stoichiometry""" + c_max = self.c_max + epsilon_s_av = self.epsilon_s_av + V_electrode = self.main_param.A_cc * self.domain_param.L + Li_max = c_max * V_electrode * epsilon_s_av + Q_max = Li_max * self.main_param.F / 3600 + return Q_max * sto + def dUdT(self, sto): """ Dimensional entropic change of the open-circuit potential [V.K-1] From c4f96c6408b32494680be42c5510d4b6a1634533 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 18 Apr 2024 00:26:44 +0000 Subject: [PATCH 19/43] style: pre-commit fixes --- .../examples/notebooks/models/DCHS.ipynb | 146 ++++++++++++------ .../open_circuit_potential/plett_ocp.py | 9 +- 2 files changed, 103 insertions(+), 52 deletions(-) diff --git a/docs/source/examples/notebooks/models/DCHS.ipynb b/docs/source/examples/notebooks/models/DCHS.ipynb index ed9cb8ae4d..838361856d 100644 --- a/docs/source/examples/notebooks/models/DCHS.ipynb +++ b/docs/source/examples/notebooks/models/DCHS.ipynb @@ -7,41 +7,60 @@ "outputs": [], "source": [ "import pybamm\n", - "import numpy as np\n", "\n", "parameters = pybamm.ParameterValues(\"Chen2020_composite\")\n", "\n", "\n", "# get the lithiation and delithiation functions\n", "\n", - "lithiation = parameters['Secondary: Negative electrode lithiation OCP [V]']\n", - "delithiation = parameters['Secondary: Negative electrode delithiation OCP [V]']\n", + "lithiation = parameters[\"Secondary: Negative electrode lithiation OCP [V]\"]\n", + "delithiation = parameters[\"Secondary: Negative electrode delithiation OCP [V]\"]\n", + "\n", "\n", "# define the new OCP function\n", "def ocp(sto):\n", - " return (lithiation(sto) + delithiation(sto))/2\n", + " return (lithiation(sto) + delithiation(sto)) / 2\n", + "\n", "\n", "# define hysteresis function\n", "def hysteresis(sto):\n", - " return (lithiation(sto) - delithiation(sto))/-2\n", + " return (lithiation(sto) - delithiation(sto)) / -2\n", "\n", - "# add additional parameters\n", - "parameters.update({\n", - " 'Secondary: Negative electrode OCP [V]': ocp,\n", - " 'Secondary: Negative particle hysteresis decay rate': 0.1,\n", - " 'Secondary: Negative electrode OCP hysteresis [V]': hysteresis,\n", - " 'Secondary: Negative particle hysteresis switching factor': 1\n", "\n", - "},check_already_exists=False)\n", - "\n", - "model = pybamm.lithium_ion.SPM({'open-circuit potential':(('single','Plett'),'single'),'particle phases':('2','1')})\n", + "# add additional parameters\n", + "parameters.update(\n", + " {\n", + " \"Secondary: Negative electrode OCP [V]\": ocp,\n", + " \"Secondary: Negative particle hysteresis decay rate\": 0.1,\n", + " \"Secondary: Negative electrode OCP hysteresis [V]\": hysteresis,\n", + " \"Secondary: Negative particle hysteresis switching factor\": 1,\n", + " },\n", + " check_already_exists=False,\n", + ")\n", "\n", + "model = pybamm.lithium_ion.SPM(\n", + " {\n", + " \"open-circuit potential\": ((\"single\", \"Plett\"), \"single\"),\n", + " \"particle phases\": (\"2\", \"1\"),\n", + " }\n", + ")\n", "\n", "\n", - "experiment = pybamm.Experiment([(\"Discharge at 1 C for 1 hour or until 2.5 V\",\"Rest for 15 minutes\"),(\"Charge at 1C until 4.2 V\",\"Hold at 4.2 V until 50 mA\",\"Rest for 15 minutes\")])\n", + "experiment = pybamm.Experiment(\n", + " [\n", + " (\"Discharge at 1 C for 1 hour or until 2.5 V\", \"Rest for 15 minutes\"),\n", + " (\n", + " \"Charge at 1C until 4.2 V\",\n", + " \"Hold at 4.2 V until 50 mA\",\n", + " \"Rest for 15 minutes\",\n", + " ),\n", + " ]\n", + ")\n", "\n", "\n", - "simulation = pybamm.Simulation(model, experiment=experiment, parameter_values=parameters)\n", + "simulation = pybamm.Simulation(\n", + " model, experiment=experiment, parameter_values=parameters\n", + ")\n", "solution = simulation.solve(calc_esoh=False)" ] }, @@ -76,13 +95,15 @@ } ], "source": [ - "solution.plot([\n", - " \"X-averaged negative electrode secondary hysteresis state\",\n", - " \"Negative electrode secondary hysteresis state\",\n", - " 'Negative electrode secondary open-circuit potential [V]',\n", - " 'Terminal voltage [V]',\n", - " 'X-averaged negative electrode secondary open-circuit potential [V]'\n", - "])" + "solution.plot(\n", + " [\n", + " \"X-averaged negative electrode secondary hysteresis state\",\n", + " \"Negative electrode secondary hysteresis state\",\n", + " \"Negative electrode secondary open-circuit potential [V]\",\n", + " \"Terminal voltage [V]\",\n", + " \"X-averaged negative electrode secondary open-circuit potential [V]\",\n", + " ]\n", + ")" ] }, { @@ -92,41 +113,60 @@ "outputs": [], "source": [ "import pybamm\n", - "import numpy as np\n", "\n", "parameters = pybamm.ParameterValues(\"Chen2020_composite\")\n", "\n", "\n", "# get the lithiation and delithiation functions\n", "\n", - "lithiation = parameters['Secondary: Negative electrode lithiation OCP [V]']\n", - "delithiation = parameters['Secondary: Negative electrode delithiation OCP [V]']\n", + "lithiation = parameters[\"Secondary: Negative electrode lithiation OCP [V]\"]\n", + "delithiation = parameters[\"Secondary: Negative electrode delithiation OCP [V]\"]\n", + "\n", "\n", "# define the new OCP function\n", "def ocp(sto):\n", - " return (lithiation(sto) + delithiation(sto))/2\n", + " return (lithiation(sto) + delithiation(sto)) / 2\n", + "\n", "\n", "# define hysteresis function\n", "def hysteresis(sto):\n", - " return (lithiation(sto) - delithiation(sto))/-2\n", + " return (lithiation(sto) - delithiation(sto)) / -2\n", "\n", - "# add additional parameters\n", - "parameters.update({\n", - " 'Secondary: Negative electrode OCP [V]': ocp,\n", - " 'Secondary: Negative particle hysteresis decay rate': 0.1,\n", - " 'Secondary: Negative electrode OCP hysteresis [V]': hysteresis,\n", - " 'Secondary: Negative particle hysteresis switching factor': 1\n", "\n", - "},check_already_exists=False)\n", - "\n", - "model = pybamm.lithium_ion.SPM({'open-circuit potential':(('single','current sigmoid'),'single'),'particle phases':('2','1')})\n", + "# add additional parameters\n", + "parameters.update(\n", + " {\n", + " \"Secondary: Negative electrode OCP [V]\": ocp,\n", + " \"Secondary: Negative particle hysteresis decay rate\": 0.1,\n", + " \"Secondary: Negative electrode OCP hysteresis [V]\": hysteresis,\n", + " \"Secondary: Negative particle hysteresis switching factor\": 1,\n", + " },\n", + " check_already_exists=False,\n", + ")\n", "\n", + "model = pybamm.lithium_ion.SPM(\n", + " {\n", + " \"open-circuit potential\": ((\"single\", \"current sigmoid\"), \"single\"),\n", + " \"particle phases\": (\"2\", \"1\"),\n", + " }\n", + ")\n", "\n", "\n", - "experiment = pybamm.Experiment([(\"Discharge at 1 C for 1 hour or until 2.5 V\",\"Rest for 15 minutes\"),(\"Charge at 1C until 4.2 V\",\"Hold at 4.2 V until 50 mA\",\"Rest for 15 minutes\")])\n", + "experiment = pybamm.Experiment(\n", + " [\n", + " (\"Discharge at 1 C for 1 hour or until 2.5 V\", \"Rest for 15 minutes\"),\n", + " (\n", + " \"Charge at 1C until 4.2 V\",\n", + " \"Hold at 4.2 V until 50 mA\",\n", + " \"Rest for 15 minutes\",\n", + " ),\n", + " ]\n", + ")\n", "\n", "\n", - "simulation = pybamm.Simulation(model, experiment=experiment, parameter_values=parameters)\n", + "simulation = pybamm.Simulation(\n", + " model, experiment=experiment, parameter_values=parameters\n", + ")\n", "solution_sigmoid = simulation.solve(calc_esoh=False)" ] }, @@ -161,13 +201,15 @@ } ], "source": [ - "solution_sigmoid.plot([\n", - " # \"X-averaged negative electrode secondary hysteresis state\",\n", - " # \"Negative electrode secondary hysteresis state\",\n", - " 'Negative electrode secondary open-circuit potential [V]',\n", - " 'Terminal voltage [V]',\n", - " 'X-averaged negative electrode secondary open-circuit potential [V]'\n", - "])" + "solution_sigmoid.plot(\n", + " [\n", + " # \"X-averaged negative electrode secondary hysteresis state\",\n", + " # \"Negative electrode secondary hysteresis state\",\n", + " \"Negative electrode secondary open-circuit potential [V]\",\n", + " \"Terminal voltage [V]\",\n", + " \"X-averaged negative electrode secondary open-circuit potential [V]\",\n", + " ]\n", + ")" ] }, { @@ -191,9 +233,15 @@ } ], "source": [ - "pybamm.QuickPlot([solution, solution_sigmoid], labels=[\"Plett\", \"Sigmoid\"],output_variables=['Negative electrode secondary open-circuit potential [V]',\n", - " 'Terminal voltage [V]',\n", - " 'X-averaged negative electrode secondary open-circuit potential [V]']).dynamic_plot()" + "pybamm.QuickPlot(\n", + " [solution, solution_sigmoid],\n", + " labels=[\"Plett\", \"Sigmoid\"],\n", + " output_variables=[\n", + " \"Negative electrode secondary open-circuit potential [V]\",\n", + " \"Terminal voltage [V]\",\n", + " \"X-averaged negative electrode secondary open-circuit potential [V]\",\n", + " ],\n", + ").dynamic_plot()" ] } ], diff --git a/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py b/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py index 3c48186aff..149ece1806 100644 --- a/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py +++ b/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py @@ -25,7 +25,6 @@ def get_coupled_variables(self, variables): phase_name = self.phase_name phase = self.phase - if self.reaction == "lithium-ion main": T = variables[f"{Domain} electrode temperature [K]"] h = variables[f"{Domain} electrode {phase_name}hysteresis state"] @@ -96,7 +95,9 @@ def get_coupled_variables(self, variables): ] = h H_x_av = pybamm.x_average(H) h_x_av = pybamm.x_average(h) - variables[f'X-averaged {domain} electrode {phase_name}hysteresis state'] = h_x_av + variables[f"X-averaged {domain} electrode {phase_name}hysteresis state"] = ( + h_x_av + ) # check if psd if domain_options["particle size"] == "distribution": # should always be true @@ -131,7 +132,9 @@ def set_rhs(self, variables): phase_name = self.phase_name current = self.param.current_with_time - current = variables[f"{Domain} electrode {phase_name}interfacial current density [A.m-2]"] + current = variables[ + f"{Domain} electrode {phase_name}interfacial current density [A.m-2]" + ] Q_cell = variables[f"{Domain} electrode capacity [A.h]"] dQdU = variables[ f"{Domain} electrode {phase_name}differential capacity [A.s.V-1]" From 5fd1555ea4edb3be2645eb6b1e5d3d9058e38135 Mon Sep 17 00:00:00 2001 From: Tanner Leo Date: Wed, 17 Apr 2024 17:41:34 -0700 Subject: [PATCH 20/43] revert to functional form of Q --- docs/source/examples/notebooks/models/DCHS.ipynb | 16 ++++++++-------- .../open_circuit_potential/plett_ocp.py | 3 ++- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/docs/source/examples/notebooks/models/DCHS.ipynb b/docs/source/examples/notebooks/models/DCHS.ipynb index 838361856d..5e6a9a44cb 100644 --- a/docs/source/examples/notebooks/models/DCHS.ipynb +++ b/docs/source/examples/notebooks/models/DCHS.ipynb @@ -72,7 +72,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "4656f55659574e728171f99ce8037aab", + "model_id": "992a4a76a92d4ae888b8065d8b96e51e", "version_major": 2, "version_minor": 0 }, @@ -86,7 +86,7 @@ { "data": { "text/plain": [ - "" + "" ] }, "execution_count": 2, @@ -172,13 +172,13 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "f1fe970ea9b94028a98720a87eb8daf2", + "model_id": "b61b1d1b47314d43962ab8968639d569", "version_major": 2, "version_minor": 0 }, @@ -192,10 +192,10 @@ { "data": { "text/plain": [ - "" + "" ] }, - "execution_count": 6, + "execution_count": 4, "metadata": {}, "output_type": "execute_result" } @@ -214,13 +214,13 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "38c1d5584ef94e30b3711fa1a78a5a3c", + "model_id": "b5db2821f7ab4da2979b66e5ff078d61", "version_major": 2, "version_minor": 0 }, diff --git a/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py b/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py index 149ece1806..0699a95884 100644 --- a/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py +++ b/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py @@ -68,7 +68,7 @@ def get_coupled_variables(self, variables): # V_electrode = self.param.A_cc * self.domain_param.L # Li_max = c_max * V_electrode * epsilon_s_av # Q_max = Li_max * self.param.F / 3600 - # dQ = Q_max * sto_bulk + # dQ = Q_max c_scale = self.phase_param.c_max variables[f"Total lithium in {phase} phase in {domain} electrode [mol]"] = ( @@ -85,6 +85,7 @@ def get_coupled_variables(self, variables): variables[f"{Domain} electrode {phase_name}OCP hysteresis [V]"] = H dU = self.phase_param.U(sto_surf, T_bulk).diff(sto_surf) + # dQ = variables[f"{Domain} electrode {phase_name}capacity [A.h]"] dQ = self.phase_param.Q(sto_surf).diff(sto_surf) dQdU = dQ / dU variables[ From 957755ef8d520962d7c0385675acaf4cdf3486e0 Mon Sep 17 00:00:00 2001 From: Tanner Leo Date: Thu, 18 Apr 2024 09:36:46 -0700 Subject: [PATCH 21/43] renaming to dchs --- docs/source/examples/notebooks/models/DCHS.ipynb | 4 ++-- pybamm/models/full_battery_models/base_battery_model.py | 4 ++-- .../lithium_ion/base_lithium_ion_model.py | 4 ++-- .../submodels/interface/open_circuit_potential/__init__.py | 2 +- .../open_circuit_potential/{plett_ocp.py => dchs_ocp.py} | 6 +++--- .../test_full_battery_models/test_lithium_ion/test_mpm.py | 4 ++-- .../test_full_battery_models/test_base_battery_model.py | 2 +- .../test_lithium_ion/base_lithium_ion_tests.py | 4 ++-- .../test_full_battery_models/test_lithium_ion/test_dfn.py | 4 ++-- .../test_full_battery_models/test_lithium_ion/test_mpm.py | 4 ++-- 10 files changed, 19 insertions(+), 19 deletions(-) rename pybamm/models/submodels/interface/open_circuit_potential/{plett_ocp.py => dchs_ocp.py} (98%) diff --git a/docs/source/examples/notebooks/models/DCHS.ipynb b/docs/source/examples/notebooks/models/DCHS.ipynb index 5e6a9a44cb..f308cf8848 100644 --- a/docs/source/examples/notebooks/models/DCHS.ipynb +++ b/docs/source/examples/notebooks/models/DCHS.ipynb @@ -40,7 +40,7 @@ "\n", "model = pybamm.lithium_ion.SPM(\n", " {\n", - " \"open-circuit potential\": ((\"single\", \"Plett\"), \"single\"),\n", + " \"open-circuit potential\": ((\"single\", \"DCHS\"), \"single\"),\n", " \"particle phases\": (\"2\", \"1\"),\n", " }\n", ")\n", @@ -235,7 +235,7 @@ "source": [ "pybamm.QuickPlot(\n", " [solution, solution_sigmoid],\n", - " labels=[\"Plett\", \"Sigmoid\"],\n", + " labels=[\"DCHS\", \"Sigmoid\"],\n", " output_variables=[\n", " \"Negative electrode secondary open-circuit potential [V]\",\n", " \"Terminal voltage [V]\",\n", diff --git a/pybamm/models/full_battery_models/base_battery_model.py b/pybamm/models/full_battery_models/base_battery_model.py index 8d4752d475..5840df2844 100644 --- a/pybamm/models/full_battery_models/base_battery_model.py +++ b/pybamm/models/full_battery_models/base_battery_model.py @@ -102,7 +102,7 @@ class BatteryModelOptions(pybamm.FuzzyDict): reactions. * "open-circuit potential" : str Sets the model for the open circuit potential. Can be "single" - (default), "current sigmoid", "Plett", or "MSMR". If "MSMR" then the "particle" + (default), "current sigmoid", "DCHS", or "MSMR". If "MSMR" then the "particle" option must also be "MSMR". A 2-tuple can be provided for different behaviour in negative and positive electrodes. * "operating mode" : str @@ -263,7 +263,7 @@ def __init__(self, extra_options): "stress and reaction-driven", ], "number of MSMR reactions": ["none"], - "open-circuit potential": ["single", "current sigmoid", "MSMR", "Plett"], + "open-circuit potential": ["single", "current sigmoid", "MSMR", "DCHS"], "operating mode": [ "current", "voltage", 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 b7462fbe94..7000869e16 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 @@ -248,9 +248,9 @@ def set_open_circuit_potential_submodel(self): ocp_model = ocp_submodels.SingleOpenCircuitPotential elif ocp_option == "current sigmoid": ocp_model = ocp_submodels.CurrentSigmoidOpenCircuitPotential - elif ocp_option == "Plett": + elif ocp_option == "DCHS": pybamm.citations.register("Wycisk2022") - ocp_model = ocp_submodels.PlettOpenCircuitPotential + ocp_model = ocp_submodels.DCHSOpenCircuitPotential elif ocp_option == "MSMR": ocp_model = ocp_submodels.MSMROpenCircuitPotential self.submodels[f"{domain} {phase} open-circuit potential"] = ocp_model( diff --git a/pybamm/models/submodels/interface/open_circuit_potential/__init__.py b/pybamm/models/submodels/interface/open_circuit_potential/__init__.py index 0004d9f2b5..c52c735aac 100644 --- a/pybamm/models/submodels/interface/open_circuit_potential/__init__.py +++ b/pybamm/models/submodels/interface/open_circuit_potential/__init__.py @@ -2,4 +2,4 @@ from .single_ocp import SingleOpenCircuitPotential from .current_sigmoid_ocp import CurrentSigmoidOpenCircuitPotential from .msmr_ocp import MSMROpenCircuitPotential -from .plett_ocp import PlettOpenCircuitPotential +from .dchs_ocp import DCHSOpenCircuitPotential diff --git a/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py b/pybamm/models/submodels/interface/open_circuit_potential/dchs_ocp.py similarity index 98% rename from pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py rename to pybamm/models/submodels/interface/open_circuit_potential/dchs_ocp.py index 0699a95884..47e9703727 100644 --- a/pybamm/models/submodels/interface/open_circuit_potential/plett_ocp.py +++ b/pybamm/models/submodels/interface/open_circuit_potential/dchs_ocp.py @@ -5,7 +5,7 @@ from . import BaseOpenCircuitPotential -class PlettOpenCircuitPotential(BaseOpenCircuitPotential): +class DCHSOpenCircuitPotential(BaseOpenCircuitPotential): def get_fundamental_variables(self): domain, Domain = self.domain_Domain phase_name = self.phase_name @@ -111,11 +111,11 @@ def get_coupled_variables(self, variables): ocp_surf = ocp_surf_eq + H * h else: raise ValueError( - 'Model type not implementted with open-circuit potential as "Plett"' + 'Model type not implementted with open-circuit potential as "DCHS"' ) else: raise ValueError( - 'Model type not implementted with open-circuit potential as "Plett"' + 'Model type not implementted with open-circuit potential as "DCHS"' ) # must not be a psd else: diff --git a/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_mpm.py b/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_mpm.py index a1d4b4a7b6..d52785a2f3 100644 --- a/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_mpm.py +++ b/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_mpm.py @@ -68,8 +68,8 @@ def test_current_sigmoid_ocp(self): modeltest = tests.StandardModelTest(model, parameter_values=parameter_values) modeltest.test_all(skip_output_tests=True) - def test_plett_ocp(self): - options = {"open-circuit potential": ("Plett", "single")} + def test_dchs_ocp(self): + options = {"open-circuit potential": ("DCHS", "single")} model = pybamm.lithium_ion.MPM(options) parameter_values = pybamm.ParameterValues("Chen2020") parameter_values = pybamm.get_size_distribution_parameters(parameter_values) 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 c56cd2304c..75047db928 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 @@ -33,7 +33,7 @@ 'lithium plating porosity change': 'false' (possible: ['false', 'true']) 'loss of active material': 'stress-driven' (possible: ['none', 'stress-driven', 'reaction-driven', 'current-driven', 'stress and reaction-driven']) 'number of MSMR reactions': 'none' (possible: ['none']) -'open-circuit potential': 'single' (possible: ['single', 'current sigmoid', 'MSMR']) +'open-circuit potential': 'single' (possible: ['single', 'current sigmoid', 'MSMR', 'DCHS']) 'operating mode': 'current' (possible: ['current', 'voltage', 'power', 'differential power', 'explicit power', 'resistance', 'differential resistance', 'explicit resistance', 'CCCV']) 'particle': 'Fickian diffusion' (possible: ['Fickian diffusion', 'fast diffusion', 'uniform profile', 'quadratic profile', 'quartic profile', 'MSMR']) 'particle mechanics': 'swelling only' (possible: ['none', 'swelling only', 'swelling and cracking']) diff --git a/tests/unit/test_models/test_full_battery_models/test_lithium_ion/base_lithium_ion_tests.py b/tests/unit/test_models/test_full_battery_models/test_lithium_ion/base_lithium_ion_tests.py index 60cefa2acd..9867a4f122 100644 --- a/tests/unit/test_models/test_full_battery_models/test_lithium_ion/base_lithium_ion_tests.py +++ b/tests/unit/test_models/test_full_battery_models/test_lithium_ion/base_lithium_ion_tests.py @@ -406,8 +406,8 @@ def test_well_posed_current_sigmoid_ocp(self): options = {"open-circuit potential": "current sigmoid"} self.check_well_posedness(options) - def test_well_posed_plett_ocp(self): - options = {"open-circuit potential": "Plett"} + def test_well_posed_dchs_ocp(self): + options = {"open-circuit potential": "DCHS"} self.check_well_posedness(options) def test_well_posed_msmr(self): diff --git a/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_dfn.py b/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_dfn.py index 3c42f5ca4f..76384f8306 100644 --- a/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_dfn.py +++ b/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_dfn.py @@ -35,9 +35,9 @@ def test_well_posed_current_sigmoid_ocp_with_psd(self): } self.check_well_posedness(options) - def test_well_posed_plett_ocp_with_psd(self): + def test_well_posed_dchs_ocp_with_psd(self): options = { - "open-circuit potential": "Plett", + "open-circuit potential": "DCHS", "particle size": "distribution", } self.check_well_posedness(options) diff --git a/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_mpm.py b/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_mpm.py index 52548c1b9b..d74a7cd934 100644 --- a/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_mpm.py +++ b/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_mpm.py @@ -116,9 +116,9 @@ def test_msmr(self): model = pybamm.lithium_ion.MPM(options) model.check_well_posedness() - def test_plett_ocp(self): + def test_dchs_ocp(self): options = { - "open-circuit potential": "Plett", + "open-circuit potential": "DCHS", } model = pybamm.lithium_ion.MPM(options) model.check_well_posedness() From d0be6377af13bca1d6c5cca3e73f3e6b3faa34be Mon Sep 17 00:00:00 2001 From: Tanner Leo Date: Thu, 18 Apr 2024 10:02:01 -0700 Subject: [PATCH 22/43] clean up --- .../open_circuit_potential/dchs_ocp.py | 36 +++++++++---------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/pybamm/models/submodels/interface/open_circuit_potential/dchs_ocp.py b/pybamm/models/submodels/interface/open_circuit_potential/dchs_ocp.py index 47e9703727..66a1ed8395 100644 --- a/pybamm/models/submodels/interface/open_circuit_potential/dchs_ocp.py +++ b/pybamm/models/submodels/interface/open_circuit_potential/dchs_ocp.py @@ -28,6 +28,7 @@ def get_coupled_variables(self, variables): if self.reaction == "lithium-ion main": T = variables[f"{Domain} electrode temperature [K]"] h = variables[f"{Domain} electrode {phase_name}hysteresis state"] + # For "particle-size distribution" models, take distribution version # of c_s_surf that depends on particle size. domain_options = getattr(self.options, domain) @@ -54,51 +55,44 @@ def get_coupled_variables(self, variables): sto_surf = sto_surf.orphans[0] T = T.orphans[0] - ocp_surf_eq = self.phase_param.U(sto_surf, T) - dUdT = self.phase_param.dUdT(sto_surf) + variables[ + f"{Domain} electrode {phase_name}hysteresis state distribution" + ] = h # Bulk OCP is from the average SOC and temperature sto_bulk = variables[f"{Domain} electrode {phase_name}stoichiometry"] - T_bulk = pybamm.xyz_average(pybamm.size_average(T)) - ocp_bulk_eq = self.phase_param.U(sto_bulk, T_bulk) - - # # get dQ, change in capacity with respect to stoichiometry - # c_max = self.phase_param.c_max - # epsilon_s_av = self.phase_param.epsilon_s_av - # V_electrode = self.param.A_cc * self.domain_param.L - # Li_max = c_max * V_electrode * epsilon_s_av - # Q_max = Li_max * self.param.F / 3600 - # dQ = Q_max - c_scale = self.phase_param.c_max variables[f"Total lithium in {phase} phase in {domain} electrode [mol]"] = ( sto_bulk * c_scale ) # c_s_vol * L * A - H = self.phase_param.H(sto_surf) + ocp_surf_eq = self.phase_param.U(sto_surf, T) variables[f"{Domain} electrode {phase_name}equilibrium OCP [V]"] = ( ocp_surf_eq ) + + T_bulk = pybamm.xyz_average(pybamm.size_average(T)) + ocp_bulk_eq = self.phase_param.U(sto_bulk, T_bulk) variables[f"{Domain} electrode {phase_name}bulk equilibrium OCP [V]"] = ( ocp_bulk_eq ) + + H = self.phase_param.H(sto_surf) variables[f"{Domain} electrode {phase_name}OCP hysteresis [V]"] = H dU = self.phase_param.U(sto_surf, T_bulk).diff(sto_surf) - # dQ = variables[f"{Domain} electrode {phase_name}capacity [A.h]"] dQ = self.phase_param.Q(sto_surf).diff(sto_surf) dQdU = dQ / dU variables[ f"{Domain} electrode {phase_name}differential capacity [A.s.V-1]" ] = dQdU - variables[ - f"{Domain} electrode {phase_name}hysteresis state distribution" - ] = h + H_x_av = pybamm.x_average(H) h_x_av = pybamm.x_average(h) variables[f"X-averaged {domain} electrode {phase_name}hysteresis state"] = ( h_x_av ) + # check if psd if domain_options["particle size"] == "distribution": # should always be true @@ -120,11 +114,14 @@ def get_coupled_variables(self, variables): # must not be a psd else: ocp_surf = ocp_surf_eq + H * h + H_s_av = pybamm.size_average(H_x_av) h_s_av = pybamm.size_average(h_x_av) ocp_bulk = ocp_bulk_eq + H_s_av * h_s_av + dUdT = self.phase_param.dUdT(sto_surf) + variables.update(self._get_standard_ocp_variables(ocp_surf, ocp_bulk, dUdT)) return variables @@ -132,11 +129,10 @@ def set_rhs(self, variables): domain, Domain = self.domain_Domain phase_name = self.phase_name - current = self.param.current_with_time current = variables[ f"{Domain} electrode {phase_name}interfacial current density [A.m-2]" ] - Q_cell = variables[f"{Domain} electrode capacity [A.h]"] + Q_cell = variables[f"{Domain} electrode {phase_name}capacity [A.h]"] dQdU = variables[ f"{Domain} electrode {phase_name}differential capacity [A.s.V-1]" ] From c2825aad70125b3032a64b8e7fcfab262a91953b Mon Sep 17 00:00:00 2001 From: Tanner Leo Date: Thu, 18 Apr 2024 17:38:42 -0700 Subject: [PATCH 23/43] update docs build script --- docs/source/examples/index.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/source/examples/index.rst b/docs/source/examples/index.rst index 8501e9cba8..df74a922cb 100644 --- a/docs/source/examples/index.rst +++ b/docs/source/examples/index.rst @@ -50,6 +50,7 @@ The notebooks are organised into subfolders, and can be viewed in the galleries notebooks/models/compare-particle-diffusion-models.ipynb notebooks/models/composite_particle.ipynb notebooks/models/coupled-degradation.ipynb + notebooks/models/DCHS.ipynb notebooks/models/DFN-with-particle-size-distributions.ipynb notebooks/models/DFN.ipynb notebooks/models/electrode-state-of-health.ipynb From a16283aa113b19fc3d0b427626c153971eeca945 Mon Sep 17 00:00:00 2001 From: Tanner Leo Date: Thu, 18 Apr 2024 17:55:45 -0700 Subject: [PATCH 24/43] update notebook --- .../examples/notebooks/models/DCHS.ipynb | 306 ++++++++++-------- 1 file changed, 180 insertions(+), 126 deletions(-) diff --git a/docs/source/examples/notebooks/models/DCHS.ipynb b/docs/source/examples/notebooks/models/DCHS.ipynb index f308cf8848..248a59504c 100644 --- a/docs/source/examples/notebooks/models/DCHS.ipynb +++ b/docs/source/examples/notebooks/models/DCHS.ipynb @@ -1,154 +1,206 @@ { "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Differential Capacity Hysteresis State model" + ] + }, { "cell_type": "code", "execution_count": 1, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Note: you may need to restart the kernel to use updated packages.\n" + ] + } + ], "source": [ + "%pip install \"pybamm[plot,cite]\" -q # install PyBaMM if it is not installed\n", "import pybamm\n", + "import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Model Equations\n", "\n", - "parameters = pybamm.ParameterValues(\"Chen2020_composite\")\n", - "\n", + "Herein the model equations for the Differential Capacity Hysteresis State open-circuit potential model are outlined, as described in Wycisk (2022).\n", "\n", - "# get the lithiation and delithiation functions\n", + "### Hysteresis State Variable\n", "\n", - "lithiation = parameters[\"Secondary: Negative electrode lithiation OCP [V]\"]\n", - "delithiation = parameters[\"Secondary: Negative electrode delithiation OCP [V]\"]\n", + "This approach utilizes a state variable to represent the degree of hysteresis at a given time and stoichiometry, $h(z,t)$. The hysteresis is treated separately from the open-circuit potential, where the potential of the electrode is written as\n", "\n", + "$$ U = U_{avg}^0(z) + H(z) \\cdot h(z,t) - \\eta $$\n", "\n", - "# define the new OCP function\n", - "def ocp(sto):\n", - " return (lithiation(sto) + delithiation(sto)) / 2\n", + "Where $H(z)$ is a function representing the hysteresis as a function of stoichiometry, $z$, and where $\\eta$ represents the sum of the overpotentials. $U_{avg}^0(z)$ is simply the average of the delithiation and lithiation open-circuit potential branches. $H(z)$ can be determined by finding the half-difference value between the lithiation and delithiation branches across the entire stoichiometry range. The state variable $h(z,t)$ is both stoichiometry and time-dependant, and spans between the range of -1 and 1. The hysteresis state variable $h(z,t)$ can be expressed in differential form with respect to time as\n", "\n", + "$$ \\frac{dh(z,t)}{dt} = \\left(\\frac{k(z) \\cdot I(t)}{Q_{cell}}\\right)\\left(1-\\text{sgn}\\left(\\frac{dz(t)}{dt}\\right) h(z,t)\\right) $$\n", "\n", - "# define hysteresis function\n", - "def hysteresis(sto):\n", - " return (lithiation(sto) - delithiation(sto)) / -2\n", + "where $ k(z) $ is expressed as \n", "\n", + "$$ k(z) = K \\cdot \\frac{1}{\\left(C_{diff}\\left(z\\right)\\right)^{x}} $$\n", "\n", - "# add additional parameters\n", - "parameters.update(\n", - " {\n", - " \"Secondary: Negative electrode OCP [V]\": ocp,\n", - " \"Secondary: Negative particle hysteresis decay rate\": 0.1,\n", - " \"Secondary: Negative electrode OCP hysteresis [V]\": hysteresis,\n", - " \"Secondary: Negative particle hysteresis switching factor\": 1,\n", - " },\n", - " check_already_exists=False,\n", - ")\n", + "And where $C_{diff}(z)$ is the differential capacity with respect to potential, expressed as \n", "\n", - "model = pybamm.lithium_ion.SPM(\n", - " {\n", - " \"open-circuit potential\": ((\"single\", \"DCHS\"), \"single\"),\n", - " \"particle phases\": (\"2\", \"1\"),\n", - " }\n", - ")\n", + "$$ C_{diff}(z) = \\frac{dQ}{dU_{avg}^0(z)} $$\n", "\n", + "Here, $Q$ is the capacity of the phase or active material experiencing the voltage hysteresis. The remaining parameters are $K$ and $x$ which are both fitting parameters that affect the response of the hysteresis state decay when passing charge in either direction.\n", "\n", - "experiment = pybamm.Experiment(\n", - " [\n", - " (\"Discharge at 1 C for 1 hour or until 2.5 V\", \"Rest for 15 minutes\"),\n", - " (\n", - " \"Charge at 1C until 4.2 V\",\n", - " \"Hold at 4.2 V until 50 mA\",\n", - " \"Rest for 15 minutes\",\n", - " ),\n", - " ]\n", - ")\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Comparing the DCHS and Current-Sigmoid model approaches\n", "\n", + "The behavior of the DCHS model is different than the current-sigmoid model approach for open-circuit potential in systems with hysteresis. Where the current-sigmoid model switches between hysteresis states simply based on the instantaneous current, the DCHS model switches based on the amount of charge passed through the active material phase while also relying on the previous hysteresis state. To assess this differentiated performance, we will compare it to the current-sigmoid model by adapting the Chen2020_composite parameter set.\n", "\n", - "simulation = pybamm.Simulation(\n", - " model, experiment=experiment, parameter_values=parameters\n", - ")\n", - "solution = simulation.solve(calc_esoh=False)" + "First we generate the model, and specify the open-circuit potential methods for the negative and positive electrodes. To maintain consistency with the parameter set, two phases for the negative electrode will be defined." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "992a4a76a92d4ae888b8065d8b96e51e", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "interactive(children=(FloatSlider(value=0.0, description='t', max=3.3439065949597495, step=0.03343906594959749…" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "solution.plot(\n", - " [\n", - " \"X-averaged negative electrode secondary hysteresis state\",\n", - " \"Negative electrode secondary hysteresis state\",\n", - " \"Negative electrode secondary open-circuit potential [V]\",\n", - " \"Terminal voltage [V]\",\n", - " \"X-averaged negative electrode secondary open-circuit potential [V]\",\n", - " ]\n", + "model_DCHS = pybamm.lithium_ion.DFN(\n", + " {\n", + " \"open-circuit potential\": ((\"single\", \"DCHS\"), \"single\"),\n", + " \"particle phases\": (\"2\", \"1\"),\n", + " }\n", + ")\n", + "\n", + "model_current_sigmoid = pybamm.lithium_ion.DFN(\n", + " {\n", + " \"open-circuit potential\": ((\"single\", \"current sigmoid\"), \"single\"),\n", + " \"particle phases\": (\"2\", \"1\"),\n", + " }\n", ")" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Next, lets define the modifications to the parameter set" + ] + }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ - "import pybamm\n", "\n", - "parameters = pybamm.ParameterValues(\"Chen2020_composite\")\n", + "parameters_DCHS = pybamm.ParameterValues(\"Chen2020_composite\")\n", + "parameters_current_sigmoid = pybamm.ParameterValues(\"Chen2020_composite\")\n", "\n", "\n", "# get the lithiation and delithiation functions\n", "\n", - "lithiation = parameters[\"Secondary: Negative electrode lithiation OCP [V]\"]\n", - "delithiation = parameters[\"Secondary: Negative electrode delithiation OCP [V]\"]\n", + "lithiation_ocp = parameters_DCHS[\"Secondary: Negative electrode lithiation OCP [V]\"]\n", + "delithiation_ocp = parameters_DCHS[\"Secondary: Negative electrode delithiation OCP [V]\"]\n", "\n", "\n", "# define the new OCP function\n", - "def ocp(sto):\n", - " return (lithiation(sto) + delithiation(sto)) / 2\n", + "def ocp_avg(sto):\n", + " return (lithiation_ocp(sto) + delithiation_ocp(sto)) / 2\n", "\n", "\n", "# define hysteresis function\n", "def hysteresis(sto):\n", - " return (lithiation(sto) - delithiation(sto)) / -2\n", + " return (lithiation_ocp(sto) - delithiation_ocp(sto)) / -2\n", "\n", "\n", "# add additional parameters\n", - "parameters.update(\n", + "parameters_DCHS.update(\n", " {\n", - " \"Secondary: Negative electrode OCP [V]\": ocp,\n", - " \"Secondary: Negative particle hysteresis decay rate\": 0.1,\n", + " \"Secondary: Negative electrode OCP [V]\": ocp_avg,\n", " \"Secondary: Negative electrode OCP hysteresis [V]\": hysteresis,\n", - " \"Secondary: Negative particle hysteresis switching factor\": 1,\n", " },\n", " check_already_exists=False,\n", - ")\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To visualize what our new ocp_avg and hysteresis state function looks like, we will plot it against stoichiometry" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAArIAAAMWCAYAAAANg2XMAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAA9hAAAPYQGoP6dpAAD7SElEQVR4nOzdd3hUZdrH8e/MpPfeeyXU0HsTEJAilhWRFbCvZe26dnDX8q4VFQtW1LWgKGKh14SA9FBCIAnpvfeemfePIQMjARJSZpLcn+uaa5I5z5xzBwP+8uQ+z6PQaDQahBBCCCGE6GaUhi5ACCGEEEKIKyFBVgghhBBCdEsSZIUQQgghRLckQVYIIYQQQnRLEmSFEEIIIUS3JEFWCCGEEEJ0SxJkhRBCCCFEtyRBVgghhBBCdEsmhi7AGKnVarKzs7G1tUWhUBi6HCGEEEKIXkOj0VBRUYGXlxdK5aXnXCXItiA7OxtfX19DlyGEEEII0WtlZGTg4+NzyTESZFtga2sLaP8A7ezsDFyNEEIIIUTvUV5ejq+vry6PXYoE2RY0txPY2dlJkBVCCCGEMIDWtHfKzV5CCCGEEKJbkiArhBBCCCG6JQmyQgghhBCiW5IeWSGEEKKXampqoqGhwdBliF7G1NQUlUrVIeeSICuEEEL0MhqNhtzcXEpLSw1diuilHBwc8PDwaPd6/RJkhRBCiF6mOcS6ublhZWUlm/+ILqPRaKiuriY/Px8AT0/Pdp3P6INsVFQUr7/+OocOHSInJ4e1a9cyb968S75n586dPProo8TFxeHr68tzzz3HkiVLuqReIYQQwpg1NTXpQqyzs7OhyxG9kKWlJQD5+fm4ubm1q83A6G/2qqqqYtCgQbz//vutGp+SksKsWbOYPHkysbGxPPzww9x5551s2rSpkysVQgghjF9zT6yVlZWBKxG9WfP3X3t7tI1+RnbmzJnMnDmz1eM/+ugjAgMDefPNNwGIiIhg9+7dvP3220yfPr2zyhRCCCG6FWknEIbUUd9/Rj8j21Z79+5l6tSpeq9Nnz6dvXv3GqgiIYQQQgjRGXpckM3NzcXd3V3vNXd3d8rLy6mpqWnxPXV1dZSXl+s9hBBCCGF8MjIyuP322/Hy8sLMzAx/f38eeughioqKLhiblJTEbbfdho+PD+bm5gQGBrJgwQIOHjyoG6NQKHQPe3t7xo4dy/bt27vySxLt0OOC7JV49dVXsbe31z18fX279Pr1TfVkV2Z36TWFEEKI7iY5OZlhw4aRmJjId999R1JSEh999BHbtm1j9OjRFBcX68YePHiQoUOHkpCQwMqVKzl58iRr166lT58+PPbYY3rn/eKLL8jJySEmJgYXFxdmz55NcnJyV395lyTr/basxwVZDw8P8vLy9F7Ly8vDzs5Od5fcXz399NOUlZXpHhkZGV1RKgAHcg8w/afp/CvqX112TSGEEKI7uv/++zEzM2Pz5s1MnDgRPz8/Zs6cydatW8nKyuLZZ58FtEs8LVmyhNDQUKKjo5k1axbBwcFERkaydOlS1q1bp3fe5jVN+/fvz4cffkhNTQ1btmxpsYaioiIWLFiAt7c3VlZWDBgwgO+++053/OOPP8bLywu1Wq33vmuvvZbbb79d9/m6desYMmQIFhYWBAUF8eKLL9LY2Kg7rlAo+PDDD5k7dy7W1ta8/PLLNDU1cccddxAYGIilpSXh4eG88847etdpbGzkwQcfxMHBAWdnZ/71r3+xePFivRWf1Go1r776qu48gwYNYs2aNW37j2EkelyQHT16NNu2bdN7bcuWLYwePfqi7zE3N8fOzk7v0VUC7AIoqysjtiCW2PzYLruuEEII0Z0UFxezadMm7rvvvgsmpjw8PFi4cCGrV69Go9EQGxtLXFwcjz32GErlhVHHwcHhotdpPnd9fX2Lx2traxk6dCh//PEHJ06c4O677+bWW29l//79APztb3+jqKiIHTt26NW+ceNGFi5cCEB0dDSLFi3ioYce4uTJk6xcuZJVq1bx8ssv611r2bJlXHfddRw/fpzbb78dtVqNj48PP/74IydPnuSFF17gmWee4YcfftC957///S/ffPMNX3zxBTExMZSXl/PLL7/onffVV1/lq6++4qOPPiIuLo5HHnmEv//97+zateuify5GS2PkKioqNEeOHNEcOXJEA2jeeustzZEjRzRpaWkajUajeeqppzS33nqrbnxycrLGyspK88QTT2ji4+M177//vkalUmk2btzY6muWlZVpAE1ZWVmHfz0teX7385r+q/prHtr+UJdcTwghRO9VU1OjOXnypKampkb3mlqt1lTVNRjkoVarW1X3n3/+qQE0a9eubfH4W2+9pQE0eXl5mtWrV2sAzeHDhy973vPPWVVVpbnvvvs0KpVKc/To0VbVpdFoNLNmzdI89thjus+vvfZaze233677fOXKlRovLy9NU1OTRqPRaKZMmaJ55ZVX9M7x9ddfazw9PfXqevjhhy977fvvv19zww036D53d3fXvP7667rPGxsbNX5+fpprr71Wo9FoNLW1tRorKyvNnj179M5zxx13aBYsWNCKr7ZjtPR92KwtOczol986ePAgkydP1n3+6KOPArB48WJWrVpFTk4O6enpuuOBgYH88ccfPPLII7zzzjv4+Pjw6aefGvXSW4v7LWZt0lq2p28nrTwNfzt/Q5ckhBCiF6lpaKLvC4ZZb/3kv6djZdb6OKLRaDpkzPkWLFiASqWipqYGV1dXPvvsMwYOHNji2KamJl555RV++OEHsrKyqK+vp66uTm9d3oULF3LXXXfxwQcfYG5uzjfffMPNN9+smx0+evQoMTExejOwTU1N1NbWUl1drTvXsGHDLrj++++/z+eff056ejo1NTXU19cTGRkJQFlZGXl5eYwYMUI3XqVSMXToUF2rQ1JSEtXV1UybNk3vvPX19QwePLhNf27GwOiD7KRJky75Dblq1aoW33PkyJFOrKpjBTsEM8FnAlGZUXwV9xXPj37e0CUJIYQQRiUkJASFQkF8fDzXXXfdBcfj4+NxdHTE1dWVsLAwAE6dOtWqcPb2228zdepU7O3tcXV1veTY119/nXfeeYfly5czYMAArK2tefjhh/VaEebMmYNGo+GPP/5g+PDhREdH8/bbb+uOV1ZW8uKLL3L99ddfcH4LCwvdx9bW1nrHvv/+ex5//HHefPNNRo8eja2tLa+//jr79u277Nd4/rUB/vjjD7y9vfWOmZubt/o8xsLog2xvsaTfEqIyo1h3Zh33Rd6Hs6VsGyiEEKJrWJqqOPlvw/zm0tK0dduTOjs7M23aND744AMeeeQRvT7Z3NxcvvnmGxYtWoRCoSAyMpK+ffvy5ptvMn/+/Av6ZEtLS/X6ZD08PAgJCWlVHTExMVx77bX8/e9/B7Q3TiUkJNC3b1/dGAsLC66//nq++eYbkpKSCA8PZ8iQIbrjQ4YM4fTp062+5vnXHjNmDPfdd5/utTNnzug+tre3x93dnQMHDjBhwgRAO9N7+PBh3axt3759MTc3Jz09nYkTJ7bp+sZIgqyRGOY+jH7O/YgrimP16dXcF3nf5d8khBBCdACFQtGmX+8byooVKxgzZgzTp0/npZdeIjAwkLi4OJ544gm8vb11v6pXKBR88cUXTJ06lfHjx/Pss8/Sp08fKisr+e2339i8efMV39gUGhrKmjVr2LNnD46Ojrz11lvk5eXpBVnQthfMnj2buLg4Xeht9sILLzB79mz8/Py48cYbUSqVHD16lBMnTvDSSy9d8tpfffUVmzZtIjAwkK+//poDBw4QGBioG/PPf/6TV199lZCQEPr06cN7771HSUmJbictW1tbHn/8cR555BHUajXjxo2jrKyMmJgY7OzsWLx48RX9uRhKj1u1oLtSKBQs6b8EgO9OfUdNY8ubNwghhBC9VWhoKAcPHiQoKIibbrqJ4OBg7r77biZPnszevXtxcnLSjR0xYgQHDx4kJCSEu+66i4iICObOnUtcXBzLly+/4hqee+45hgwZwvTp05k0aRIeHh56S1s1u+qqq3BycuL06dPccsstesemT5/O77//zubNmxk+fDijRo3i7bffxt//0vfI3HPPPVx//fXMnz+fkSNHUlRUpDc7C/Cvf/2LBQsWsGjRIkaPHo2NjQ3Tp0/Xa1n4z3/+w/PPP8+rr75KREQEM2bM4I8//tALxN2FQtPWjuheoLy8HHt7e8rKyrp0Ka5GdSOz184mqzKL50Y+x/w+87vs2kIIIXqH2tpaUlJSCAwM1As3omdSq9VERERw00038Z///MfQ5ehc6vuwLTlMZmSNiInShFv73grAlye/pEndZOCKhBBCCNGdpKWl8cknn5CQkMDx48e59957SUlJuWBWuKeQIGtkrgu5DjszOzIqMtiRsePybxBCCCGEOEupVLJq1SqGDx/O2LFjOX78OFu3biUiIsLQpXUK4+/s7mWsTK2YHz6fT45/whdxXzDFb4quQVsIIYQQ4lJ8fX2JiYkxdBldRmZkjdAtEbdgqjTlWMExjuR3n/VwhRBCCCG6kgRZI+Ri6cLc4LkAfHzsYwNXI4QQQghhnCTIGqk7BtyBSqEiJjuGYwXHDF2OEEIIIYTRkSBrpHxtfZkTPAeAD49+aOBqhBBCCCGMjwRZI3b3gLtRKVTsztrN8YLjhi5HCCGEEMKoSJA1Yr52vswKmgXIrKwQQgghxF9JkDVydw+8G6VCSXRWNCcKTxi6HCGEEKJXW7VqFQ4ODrrPly1bRmRk5CXfk5qaikKhIDY2ttXn7aj6ejoJskbO386fWYHaWdmPjn5k4GqEEEIIw8rIyOD222/Hy8sLMzMz/P39eeihhygqKrpgbFJSErfddhs+Pj6Ym5sTGBjIggULOHjwoG6MQqHQPezt7Rk7dizbt29vdT2PP/4427Zt032+ZMkS5s2b1+ava/78+SQkJLTpPQEBASxfvrzd5+nOJMh2A82zsrsydxFXFGfocoQQQgiDSE5OZtiwYSQmJvLdd9+RlJTERx99xLZt2xg9ejTFxcW6sQcPHmTo0KEkJCSwcuVKTp48ydq1a+nTpw+PPfaY3nm/+OILcnJyiImJwcXFhdmzZ5OcnNyqmmxsbHB2dm7312ZpaYmbm5vRnKe7kCBrBEqr6zmZXX7R4wH2AVwTeA0AH8XKrKwQQoje6f7778fMzIzNmzczceJE/Pz8mDlzJlu3biUrK4tnn30WAI1Gw5IlSwgNDSU6OppZs2YRHBxMZGQkS5cuZd26dXrndXBwwMPDg/79+/Phhx9SU1PDli1bWlXT+a0Fy5Yt48svv2TdunW6Wd6dO3fqxiYnJzN58mSsrKwYNGgQe/fu1R37a0vAmTNnuPbaa3F3d8fGxobhw4ezdetW3fFJkyaRlpbGI488ortWS+cB+PDDDwkODsbMzIzw8HC+/vprveMKhYJPP/2U6667DisrK0JDQ/n1119b9fUbmgRZA4tJKmTwf7bw4PeX3sGreVZ2Z+ZOThad7KLqhBBCCONQXFzMpk2buO+++7C0tNQ75uHhwcKFC1m9ejUajYbY2Fji4uJ47LHHUCovjDqX6iFtPnd9fX2ba3z88ce56aabmDFjBjk5OeTk5DBmzBjd8WeffZbHH3+c2NhYwsLCWLBgAY2NjS2eq7KykmuuuYZt27Zx5MgRZsyYwZw5c0hPTwfg559/xsfHh3//+9+6a7Vk7dq1PPTQQzz22GOcOHGCe+65h9tuu40dO3bojXvxxRe56aabOHbsGNdccw0LFy7Um+E2VhJkDay/lz0KICm/kpyymouOC7QPZEbADEBWMBBCCNHBNBqorzLMQ6NpVYmJiYloNBoiIiJaPB4REUFJSQkFBQUkJiYC0KdPnzb9MVRXV/Pcc8+hUqmYOHFim94L2jYDS0tLzM3N8fDwwMPDAzMzM93xxx9/nFmzZhEWFsaLL75IWloaSUlJLZ5r0KBB3HPPPfTv35/Q0FD+85//EBwcrJspdXJyQqVSYWtrq7tWS9544w2WLFnCfffdR1hYGI8++ijXX389b7zxht64JUuWsGDBAkJCQnjllVeorKxk//79bf4z6Gomhi6gt7O3MmWAjwNHM0rZnVjI34b5XnTsPYPuYUPKBnZm7ORowVEGuQ7qukKFEEL0XA3V8IqXYa79TDaYWbd6uKYVwbc1Y863YMECVCoVNTU1uLq68tlnnzFw4MA2naM1zj+np6cnAPn5+S0G7srKSpYtW8Yff/xBTk4OjY2N1NTU6GZkWys+Pp67775b77WxY8fyzjvvXLQ2a2tr7OzsyM/Pb9O1DEFmZI3A+BAXAHYnFV5yXJB9EHOD5wLw9qG32/wXVQghhOiuQkJCUCgUxMfHt3g8Pj4eR0dHXF1dCQsLA+DUqVOtOvfbb79NbGwsubm55Obmsnjx4g6r+3ympqa6j5t7WtVqdYtjH3/8cdauXcsrr7xCdHQ0sbGxDBgw4IpaHtpaW3N9F6vNmMiMrBEYG+LCih1JxCQVotFodN/cLXlg8ANsSNnAobxDRGdFM8FnQhdWKoQQokcytdLOjBrq2q3g7OzMtGnT+OCDD3jkkUf0+mRzc3P55ptvWLRoEQqFgsjISPr27cubb77J/PnzL+iTLS0t1euT9fDwICQkpEO+HDMzM5qamtp9npiYGJYsWcJ1110HaGdoU1NT23ytiIgIYmJi9MJ5TEwMffv2bXeNxkBmZI3AEH8HLE1VFFbWcyq34pJjPaw9WBixENDOyjap2/+XRQghRC+nUGh/vW+IxyUmb/5qxYoV1NXVMX36dKKiosjIyGDjxo1MmzYNb29vXn755bNfjoIvvviChIQExo8fz/r160lOTubYsWO8/PLLXHvttZ31J0lAQADHjh3j9OnTFBYW0tDQcEXnCQ0N5eeffyY2NpajR49yyy23XDBDGhAQQFRUFFlZWRQWtvxb3SeeeIJVq1bx4YcfkpiYyFtvvcXPP//M448/fkV1GRsJskbA3ETFyCAnAHYnXrq9AOCOAXdga2ZLUmkSv57pHstjCCGEEO0VGhrKwYMHCQoK4qabbiI4OJi7776byZMns3fvXpycnHRjR4wYwcGDBwkJCeGuu+4iIiKCuXPnEhcXd8EmAh3prrvuIjw8nGHDhuHq6kpMTMwVneett97C0dGRMWPGMGfOHKZPn86QIUP0xvz73/8mNTWV4OBgXF1dWzzPvHnzeOedd3jjjTfo168fK1eu5IsvvmDSpElXVJexUWik0fIC5eXl2NvbU1ZWhp2dXZdc89PoZF76I56JYa58efuIy47/4sQXvHXoLdyt3Pn9ut+xMLHogiqFEEJ0d7W1taSkpBAYGIiFhfy/QxjGpb4P25LDZEbWSIwL1d7wtS+liLrGy7cL3BJxCx7WHuRV5/HtqW87uzwhhBBCCKMjQdZIhLvb4mprTm2DmkNpJZcdb64y54HIBwD49PinlNWVdXaJQgghhBBGRYKskVAoFIxrXoarFX2yALODZhPqGEpFfQWfHv+0M8sTQgghhDA6EmSNyNizQTbmMuvJNlMpVTw85GEAvo3/lpzKlrenE0IIIYToiSTIGpHmGdljWWWUVrduwePx3uMZ5j6MenU9bx9+uzPLE0IIIYQwKhJkjYiHvQWhbjZoNLDnTFGr3qNQKHh8+OMoUOg2ShBCCCGE6A0kyBqZ5tULolvZJwvQz7kf14deD8Cr+16VTRKEEEII0StIkDUy49rYJ9vswSEPYmtmy+mS06xJWNMZpQkhhBBCGBUJskZmZJAzJkoF6cXVpBdVt/p9ThZOuuW43ot9j9La0k6qUAghhBDCOEiQNTI25iYM8XMEIDqpoE3vvSn8JkIdQymrK+O9I+91RnlCCCGE+ItVq1bh4ODQpvcoFAp++eUXAFJTU1EoFMTGxl7yPZMmTeLhhx9u9Xnbo6PO09kkyBqhti7D1cxEacLTI54G4MeEH4kviu/w2oQQQghDysjI4Pbbb8fLywszMzP8/f156KGHKCq68CbppKQkbrvtNnx8fDA3NycwMJAFCxZw8OBB3RiFQqF72NvbM3bsWLZv396VXxK+vr7k5OTQv39/AHbu3IlCoaC0tLTN58rJyWHmzJmtHr9s2TIiIyPbfR5DkSBrhJpv+IpJKqJJrWnTe4d7DGdGwAw0aHh1/6toNG17vxBCCGGskpOTGTZsGImJiXz33XckJSXx0UcfsW3bNkaPHk1xcbFu7MGDBxk6dCgJCQmsXLmSkydPsnbtWvr06cNjjz2md94vvviCnJwcYmJicHFxYfbs2SQnJ3fZ16VSqfDw8MDExKTd5/Lw8MDc3NxoztPZJMgaoUE+9tiam1BW08CJrLZvPfvYsMewNLHkSP4R/kj5oxMqFEIIIbre/fffj5mZGZs3b2bixIn4+fkxc+ZMtm7dSlZWFs8++ywAGo2GJUuWEBoaSnR0NLNmzSI4OJjIyEiWLl3KunXr9M7r4OCAh4cH/fv358MPP6SmpoYtW7ZctI5Vq1bh5+eHlZUV1113XYuzwevWrWPIkCFYWFgQFBTEiy++SGNjY4vnO7+1IDU1lcmTJwPg6OiIQqFgyZIlurFqtZonn3wSJycnPDw8WLZsmd65/toS8K9//YuwsDCsrKwICgri+eefp6GhQfd1vPjiixw9elQ3K71q1aoWz3P8+HGuuuoqLC0tcXZ25u6776ayslJ3fMmSJcybN4833ngDT09PnJ2duf/++3XX6iwSZA2tsR5yjsKZHbqXTFRKRgU7AxCV0LY+WQAPaw/uGnAXAG8dfIvK+srLvEMIIYQwbsXFxWzatIn77rsPS0tLvWMeHh4sXLiQ1atXo9FoiI2NJS4ujsceewyl8sKoc6l+1uZz19e3vDHRvn37uOOOO3jggQeIjY1l8uTJvPTSS3pjoqOjWbRoEQ899BAnT55k5cqVrFq1ipdffvmyX6evry8//fQTAKdPnyYnJ4d33nlHd/zLL7/E2tqaffv28dprr/Hvf//7kqHb1taWVatWcfLkSd555x0++eQT3n5bu4HS/Pnzeeyxx+jXrx85OTnk5OQwf/78C85RVVXF9OnTcXR05MCBA/z4449s3bqVBx54QG/cjh07OHPmDDt27ODLL79k1apVumDcWSTIGlrmflg5AX79p97LV/VxA2DrqfwrOu2ifovws/WjoKaA5YeXt7dKIYQQPZhGo6G6odogj9a2wCUmJqLRaIiIiGjxeEREBCUlJRQUFJCYmAhAnz592vTnUF1dzXPPPYdKpWLixIktjnnnnXeYMWMGTz75JGFhYTz44INMnz5db8yLL77IU089xeLFiwkKCmLatGn85z//YeXKlZetQaVS4eTkBICbmxseHh7Y29vrjg8cOJClS5cSGhrKokWLGDZsGNu2bbvo+Z577jnGjBlDQEAAc+bM4fHHH+eHH34AtKHdxsYGExMTPDw88PDwuOCHBIBvv/2W2tpavvrqK/r3789VV13FihUr+Prrr8nLy9ONc3R0ZMWKFfTp04fZs2cza9asS9bWEdrfjCHax2OA9rksA6qLwUr7zTvlbJA9mlFKfnktbnYWbTqtucqcF0a/wJ2b72T16dXMCprFYLfBHVq6EEKInqGmsYaR3440yLX33bIPK1OrVo9vTfBt6/0hCxYsQKVSUVNTg6urK5999hkDBw5scWx8fDzXXXed3mujR49m48aNus+PHj1KTEyM3gxsU1MTtbW1VFdXY2XV+q/3r/5al6enJ/n5F5/0Wr16Ne+++y5nzpyhsrKSxsZG7Ozs2nTN+Ph4Bg0ahLW1te61sWPHolarOX36NO7u7gD069cPlUqlV9vx48fbdK22khlZQ7OwBwd/7ce55/5ju9lZMMjXAYBtVzgrO9JzJNeFaP+yLd2zlPqmln9NIoQQQhi7kJAQFAoF8fEtr8gTHx+Po6Mjrq6uhIWFAXDq1KlWnfvtt98mNjaW3NxccnNzWbx4cbtqrays5MUXXyQ2Nlb3OH78OImJiVhYtG1i6q9MTU31PlcoFKjV6hbH7t27l4ULF3LNNdfw+++/c+TIEZ599tmLtk20V1tq6ygyI2sMPAdCaRrkHoOgc7/KmBbhxtGMUrbF57FghN8VnfqxYY8RlRlFSlkKnx7/lPsi7+uoqoUQQvQQliaW7Ltln8Gu3RrOzs5MmzaNDz74gEceeUTvV+C5ubl88803LFq0CIVCQWRkJH379uXNN99k/vz5F/TJlpaW6vXJenh4EBIS0qo6IiIi2LdP/8/qzz//1Pt8yJAhnD59utXn/CszMzNAO4vbHnv27MHf3193ExxAWlraBde63HUiIiJYtWoVVVVVulnZmJgYlEol4eHh7aqxvWRG1hh4DNI+5+pPv0+J0E7VRycWUlN/Zd/M9ub2PD1Su7bsJ8c/Iakk6crrFEII0SMpFAqsTK0M8lAoFK2uc8WKFdTV1TF9+nSioqLIyMhg48aNTJs2DW9vb92v8hUKBV988QUJCQmMHz+e9evXk5yczLFjx3j55Ze59tprr/jP6sEHH2Tjxo288cYbJCYmsmLFCr22AoAXXniBr776ihdffJG4uDji4+P5/vvvee6551p1DX9/fxQKBb///jsFBQV6qwO0RWhoKOnp6Xz//fecOXOGd999l7Vr1+qNCQgIICUlhdjYWAoLC6mrq7vgPAsXLsTCwoLFixdz4sQJduzYwT//+U9uvfVWXVuBoUiQNQaeZ/tdco7pvdzHwxZvB0vqGtXsbuPmCOe72v9qJvlMolHdyLK9y1BrOneaXwghhOgMoaGhHDx4kKCgIG666SaCg4O5++67mTx5Mnv37tXdJAUwYsQIDh48SEhICHfddRcRERHMnTuXuLg4li9ffsU1jBo1ik8++YR33nmHQYMGsXnz5gsC6vTp0/n999/ZvHkzw4cPZ9SoUbz99tv4+/u36hre3t66G8bc3d0vWB2gtebOncsjjzzCAw88QGRkJHv27OH555/XG3PDDTcwY8YMJk+ejKurK999990F57GysmLTpk0UFxczfPhwbrzxRqZMmcKKFSuuqK6OpNDIivkXKC8vx97enrKysjY3RF/ZBbPhrQhQqOCZLDA99+uSZb/GsWpPKvOH+fLfG1tuPG+N3Kpc5q2bR1VDFc+MfIYFfRZ0ROVCCCG6mdraWlJSUggMDGx3v6YQV+pS34dtyWEyI2sMbD3BygU0TZB3Uu/Q1LPtBdtO5aNu4y5f5/Ow9uDhIQ8DsPzQcnKrcq/4XEIIIYQQxkCCrDFQKM61F+TqtxeMCHTC1tyEwso6jmaWtusyN4XfRKRrJNWN1Szbs0y2rxVCCCFEtyZB1lg0ryf7lyBrZqJkQrgrAFvj8/76rjZRKpS8OOZFzFXmxGTH8MPpH9p1PiGEEEIIQ5Igayw8Wr7hC2Da2faCrSevbD3Z8wU5BOlaDN489CapZantPqcQQgghhCFIkDUWnmeX4MqLA7X+UluTwl1RKRWczqsgvai63Ze6JeIWRnqOpKaxhmd2P0OjurHd5xRCCCGE6GoSZI2FUxCYWkNjDRTpr/XqYGXGMH9HoP3tBaBtMXhp7EvYmtpyvPA4nx7/tN3nFEII0b3IfRLCkDrq+0+CrLFQqsC9n/bjltoL+javXtD+IAvaVQyeGfUMACuPriSuMK5DziuEEMK4NW8jWl3d/t/wCXGlmr///rqtbVvJFrXGxHMgZO6H3KMw8G96h6ZEuPPSH/HsSy6mrKYBe8v2/YcHmBU4ix3pO9ictpmndz/ND7N/wMJE1hQUQoieTKVS4eDgQH6+9r4LK6u27a4lRHtoNBqqq6vJz8/HwcEBlUrVrvNJkDUmzTd8/WWrWoBAF2tC3GxIyq9kV0IBcwd5tftyCoWC50c9z5H8I6SUpbD88HKeGvFUu88rhBDCuHl4eADowqwQXc3BwUH3fdgeEmSNyflb1Wo02vVlzzMlwo2k/Eq2nszrkCAL4GDhwL/H/pt7t97LN/HfMMZrDBN8JnTIuYUQQhgnhUKBp6cnbm5uNDQ0GLoc0cuYmpq2eya2mQRZY+J6dpvammIozwJ7H73D0yLcWbkrmR2n86lvVGNm0jEtzuO8x3FLn1v49tS3PLv7WX6c8yMe1u3/KUkIIYRxU6lUHRYohDCEbnGz1/vvv09AQAAWFhaMHDmS/fv3X3L88uXLCQ8Px9LSEl9fXx555BFqa2u7qNp2MLUA1z7aj1toLxjs54irrTkVtY1EJxZ06KUfG/YYEU4RlNaV8mTUk7IklxBCCCGMntEH2dWrV/Poo4+ydOlSDh8+zKBBg5g+ffpF+3q+/fZbnnrqKZYuXUp8fDyfffYZq1ev5plnnuniyq+Q58U3RlApFcwa4AnAb0ezO/SyZioz3pz4JjamNhzJP8KKIys69PxCCCGEEB3N6IPsW2+9xV133cVtt91G3759+eijj7CysuLzzz9vcfyePXsYO3Yst9xyCwEBAVx99dUsWLDgsrO4RkN3w9eFQRZgztne2C0n86ipb2pxzJXytfNl2ZhlAHx24jN2Z+3u0PMLIYQQQnQkow6y9fX1HDp0iKlTp+peUyqVTJ06lb1797b4njFjxnDo0CFdcE1OTmb9+vVcc801F71OXV0d5eXleg+D8RigfW5hRhZgiJ8D3g6WVNU3seN0x99tOj1gOvPD5wPwTPQz5FV1zLq1QgghhBAdzaiDbGFhIU1NTbi7u+u97u7uTm5ubovvueWWW/j3v//NuHHjMDU1JTg4mEmTJl2yteDVV1/F3t5e9/D19e3Qr6NNmoNsWTrUlFxwWKFQMHtQ57QXNHti+BNEOEVQUlci/bJCCCGEMFpGHWSvxM6dO3nllVf44IMPOHz4MD///DN//PEH//nPfy76nqeffpqysjLdIyMjowsr/gtLB3Dw137cwg1fAHMGatsLtp/Kp6K245dNMVeZ88bEN7A2teZw/mHplxVCCCGEUTLqIOvi4oJKpSIvT//X23l5eRddRPf555/n1ltv5c4772TAgAFcd911vPLKK7z66quo1eoW32Nubo6dnZ3ew6AuccMXQD8vO4JcralrVLM1vnN+9e9n56fXL7spdVOnXEcIIYQQ4koZdZA1MzNj6NChbNu2TfeaWq1m27ZtjB49usX3VFdXo1Tqf1nNa+RpNJrOK7YjXeaGL4VCoZuV/e1oTqeVMSNgBkv6LQHg+ZjnOV18utOuJYQQQgjRVkYdZAEeffRRPvnkE7788kvi4+O59957qaqq4rbbbgNg0aJFPP3007rxc+bM4cMPP+T7778nJSWFLVu28PzzzzNnzpzus+jzJbaqbTbnbJ9sVEIBJVX1nVbKQ0MeYrTnaGoaa3hox0OU1pZ22rWEEEIIIdrC6Hf2mj9/PgUFBbzwwgvk5uYSGRnJxo0bdTeApaen683APvfccygUCp577jmysrJwdXVlzpw5vPzyy4b6EtquubWg4DQ01ICp5QVDQtxsifC0Iz6nnI1xuSwY4dcppZgoTXh94uvc/PvNZFZm8njU43w09SNMlEb/rSOEEEKIHk6h6Ta/b+865eXl2NvbU1ZWZph+WY0GXg+B6kK4azt4D21x2Ac7k3ht42nGBDvz7V2jOrWkhJIE/r7+79Q01nBr31t5cviTnXo9IYQQQvRObclhRt9a0CspFJddTxbOrV6wN7mI/PLO3YI3zDGMl8dpZ7W/Pvk1v535rVOvJ4QQQghxORJkjZXXYO1z9uGLDvF1siLS1wGNBtYf77ybvppN85/G3QPvBmDZnmUcLTja6dcUQgghhLgYCbLGyme49jnjwCWHzT27Ze1vxzo/yALcH3k/k3wmUa+u58HtD5JRbsA1d4UQQgjRq0mQNVY+w7TPBaegtuyiw2YN9EShgENpJWSWVHd6WUqFkv9O+C8RThEU1xZz37b7KKu7eH1CCCGEEJ1FgqyxsnE7u8OXBrIu3l7gbmfByEAnoHPXlD2flakVK6aswMPag9TyVB7c/iD1TZ23BJgQQgghREskyBqz5vaCzIOXHDYv0huAHw9ldNmmD25Wbnww5QNsTG04nH+Y52KeQ61peec0IYQQQojOIEHWmOmC7KX7ZGcP8sLKTEVyQRUH00q6oDCtUMdQ3pr0FiYKEzakbGDFkRVddm0hhBBCCAmyxuz8IHuJmVYbcxNmD9Tu9PX9/q69+Wq012iWjlkKwCfHP2FNwpouvb4QQgghei8JssbMYwCozKGmGIqTLzl0/nDtzl5/HM+mvLahK6rTmRcyj38M+gcA//nzP2xN29ql1xdCCCFE7yRB1piZmIHnIO3Hl+mTHeLnQKibDbUNan6Nze6C4vTdN+g+rg+9HrVGzZNRT7I3e2+X1yCEEEKI3kWCrLFrZZ+sQqFg/nBfAFYf6Pq1XRUKBS+MeoFp/tNoUDfw0I6HZMMEIYQQQnQqCbLGrnk92csEWYDrh/hgqlJwPKuME1ldv7arSqni/8b/H2O8xlDTWMN9W+8joSShy+sQQgghRO8gQdbYNc/I5p2A+ktveOBkbcbV/TwA+OGgYXbcMlOZ8faktxnkOojy+nLu2XIPGRWy+5cQQgghOp4EWWNn7wM2HqBuhJzL/6r+5rPtBWuPZFHb0NTZ1bXIytSK96e8T6hjKIU1hdy1+S7yqvIMUosQQgghei4JssZOoWhTe8HYYBe8HSypqG1kw4mu2emrJfbm9qycuhJfW1+yKrO4Y/MdEmaFEEII0aEkyHYHrbzhC0CpPHfTV1evKftXrlaufHr1p3jbeJNWnsYdm+8gvzrfoDUJIYQQoueQINsdtHKr2mY3DvVBqYB9KcUkF1R2YmGX52XjxWfTP8PL2ou08jRu33S7hFkhhBBCdAgJst2BVyQoVFCRDWVZlx/uYMnEMFcAfjiY2cnFXZ63jTefz/hcF2bv2CQzs0IIIYRoPwmy3YGZNbj3037civYCOLfT15pDmdQ3qjurslY7P8ymlqdyx6Y7KKguMHRZQgghhOjGJMh2F2244QtgSoQbrrbmFFbWsf644W76Ol9zmPW09iS1PJXbNt1GTqVx1CaEEEKI7keCbHfRxj5ZU5WSRaP8Afh0dzIajaazKmsTbxtvPp9+rs1g0cZFpJalGrosIYQQQnRDEmS7i+YgmxMLjfWtesvCUf6Ymyg5kVXO/pTizqutjXxsffhy5pcE2AWQW5XL4o2LOV182tBlCSGEEKKbkSDbXTgFg4UDNNZqd/lqzVuszbh+iA8An+1O6cTi2s7D2oMvZ35JhFMExbXF3LbpNmLzYw1dlhBCCCG6EQmy3YVSeV6fbOvaCwDuGBcAwJb4PFILqzqhsCvnZOHEp9M/ZbDbYCrqK7h7y93szd5r6LKEEEII0U1IkO1O2rAxQrMQN1smhbui0cCqPamdU1c72JnZsXLaSsZ6jaWmsYb7t93PptRNhi5LCCGEEN2ABNnupI0rFzS7c1wQAD8czKCspqGjq2o3SxNL3r3qXab5T6NB3cATu57gq7ivDF2WEEIIIYycBNnuxHsYoICSFKjIbfXbxoY408fDlur6Jr7fn9559bWDmcqM1ye8zs3hN6NBw+sHX+e/+/+LWmP4NXCFEEIIYZwkyHYnlg7gMUD7ceruVr9NoVBw+7hAQNte0NBknOFQpVTxzMhneHToowD8L/5/PL7rcWobaw1cmRBCCCGMkQTZ7iZgvPY5JapNb5s7yAsXGzNyymrZcKL1s7ldTaFQcFv/23htwmuYKk3ZkraFu7fcTWltqaFLE0IIIYSRkSDb3QSeDbJtmJEFsDBVceuoAAA+izaeDRIuZmbgTFZOW4mtmS1H8o9w64ZbZeMEIYQQQuiRINvd+I0GhRKKz0B5dpveunCUH2YmSo5mlnEoraSTCuw4wz2G89WMr3Rb2t6y/hb2ZO8xdFlCCCGEMBISZLsbSwfwGKj9uI2zsi425lw/2BuAj3ad6eDCOkeIYwjfzvqWQa6DqKiv4L6t9/Ft/LdGP6MshBBCiM4nQbY7CryyPlmAuycEoVTA1vh8jmWWdmxdncTF0oXPp3/O3OC5NGmaeHX/q7z050s0qI1vKTEhhBBCdB0Jst1RwJX1yQIEudowL1I7K7t8a2JHVtWpzFRmvDT2JR4Z+ggKFPyQ8AP3bLmHklrjb5EQQgghROeQINsdNffJlqRAWWab3/7PKaGolAq2n8onNqO04+vrJAqFgtv73867V72LlYkVB3IPcPPvNxNXFGfo0oQQQghhABJkuyMLO/CM1H6cEt3mtwe6WJ83K5vQgYV1jUm+k/jfNf/D19aX7KpsFq1fxM+JPxu6LCGEEEJ0MQmy3dUVLsPV7J9XhaBSKth5uoDD6d3v1/OhjqF8P/t7JvpMpF5dz9I9S1m2Zxl1TXWGLk0IIYQQXUSCbHcVMEH7nNr2G74AAlysuW5w9+uVPZ+dmR3vXvUuD0Q+gAIFPyX+xOINi8mpzDF0aUIIIYToAhJkuyu/kaBQQWk6lKRd0SmaZ2WjEgq6xbqyLVEqlNwz6B4+nPoh9ub2xBXFcdPvNxGVeWUBXwghhBDdhwTZ7srcFryHaD++wvYCf2drbhjSfXtlzzfWeyyrZ6+mr3NfSutKuX/b/bx+4HUammSJLiGEEKKnkiDbnemW4Wr7DV/N/nlVKCZKBdGJhRxKK+6gwgzD28abr2d+zcKIhQB8dfIrFm1YREZFhoErE0IIIURnkCDbnQWM0z6n7oYr3OnK18mKG4f6APD2lu7ZK3s+M5UZT414incmv4OdmR0nik5w0283sTF1o6FLE0IIIUQHkyDbnfmNAqUJlGVASeoVn+b+ySGYKBXsTiokJqmw4+ozoKv8rmLNnDVEukZS2VDJE7ueYOmepVQ3VBu6NCGEEEJ0EAmy3ZmZNXgP1X58hX2yoJ2V/fsofwD+8/tJGpvUHVGdwXnaePL5jM+5c8CdKFDwc+LP3PjbjcTmxxq6NCGEEEJ0AAmy3V0H9MkCPDQlFHtLU07lVvD9gZ7TU2qqNOWhIQ/x2fTP8LD2IKMig8UbF7PiyAoa1HIjmBBCCNGdSZDt7po3RkiJvuI+WQBHazMemRoKwFtbEiir6Vkhb7jHcH6a+xOzgmah1qhZeWwli9YvIqUsxdClCSGEEOIKSZDt7nxGgNIUKrKhOLldp1o4yp8QNxuKq+p5b1v3v/Hrr+zM7Pi/8f/H6xNex9bMVncj2Ncnv6ZJ3WTo8oQQQgjRRhJkuzszK/AZrv24ne0Fpiolz82KAGDVnlSSCyrbW51RmhE4g5/n/swoz1HUNtXy2oHXuG3TbaSWpRq6NCGEEEK0gQTZniDw7Ha1Z7a3+1STwt2YHO5Ko1rDK+vj230+Y+Vh7cHH0z7m+VHPY2VixZH8I9z42418GfelzM4KIYQQ3YQE2Z4gdJr2+cwO6ICdrJ6d1RcTpYKt8flEJxa0+3zGSqFQcFP4Tay9di2jPEdR11THGwffYPHGxSSXta9NQwghhBCdT4JsT+A1BKxcoK4c0v9s9+lC3Gy4dXTPW47rYrxsvPh42scsHb0Ua1NrjhYc5cZfb+TD2A+pb6o3dHlCCCGEuAgJsj2BUnluVjZxU4ec8uEpYThYmZKQV8m3+9M75JzGTKFQcGPYjaydu5Zx3uNoUDfwwdEPuPG3GzmUd8jQ5QkhhBCiBR0WZJ2cnNr0cHZ2Ji0traMuL5qDbMLmDjmdvZUpj00LA+D1jafJLavtkPMaO08bTz6Y8gGvT3gdZwtnUspSWLJxCcv2LKOsrszQ5QkhhBDiPAqNph2Lj55HqVSyfPly7O3tLztWo9Fw3333ceLECYKCgjri8h2qvLwce3t7ysrKsLOzM3Q5rVNTCq8FgaYJHjoKjgHtPmWTWsMNH+4hNqOUqRFufLJoGAqFot3n7S7K6sp4+9Db/JT4EwBOFk48PuxxZgfN7lV/DkIIIURXaksO69Agm5ubi5ubW6vG29racvToUQmyHemLayAtBq55A0bc1SGnTMirYNa70TQ0aXh3wWDmDvLqkPN2J4fyDvHvvf/W3QA2xG0Iz4x8hnCncANXJoQQQvQ8bclhHdZaoFarWx1iASoqKowyxHZroVdrnxM6pk8WIMzdlgcma3f8WvZrHEWVdR127u5iqPtQfpzzIw8NeQhLE0sO5x9m/u/z+e/+/1JRX2Ho8oQQQoheq0Nv9vr9999Rqzv+Dvf333+fgIAALCwsGDlyJPv377/k+NLSUu6//348PT0xNzcnLCyM9evXd3hdRqc5yKZGQ311h5323knB9PGwpbiqnhd/O9lh5+1OzFRm3DngTn6d9yvT/KfRpGnif/H/Y87aOaxLWoda07NXdhBCCCGMUYcG2Xnz5uHr68uzzz5LUlJSh5xz9erVPProoyxdupTDhw8zaNAgpk+fTn5+fovj6+vrmTZtGqmpqaxZs4bTp0/zySef4O3t3SH1GDW3CLD3hcZaSInqsNOamSj57w0DUSrg16PZbD2Z12Hn7m48rD14a9JbrJy2kgC7AIpqi3gu5jlu+eMWjuQfMXR5QgghRK/SoUE2JSWFe+65h++//57w8HAmTpzI119/TU1NzRWf86233uKuu+7itttuo2/fvnz00UdYWVnx+eeftzj+888/p7i4mF9++YWxY8cSEBDAxIkTGTRo0BXX0G0oFOdmZRM7ZvWCZoN8HbhrvLYV5LlfTlBe2/6NF7qzMV5j+GnuTzwy9BGsTa2JK4pj0YZFPLnrSbIrsw1dnhBCCNErdGiQ9fX15YUXXuDMmTNs3bqVgIAA7r33Xjw9PfnHP/7BgQMH2nS++vp6Dh06xNSpU88VrFQydepU9u7d2+J7fv31V0aPHs3999+Pu7s7/fv355VXXqGp6eLbjtbV1VFeXq736LbCpmufEzdDx9zHp/PItDACnK3ILa/l1R68fW1rmanMuL3/7fx+3e/cEHoDChRsSN3A3F/m8t6R96hqqDJ0iUIIIUSP1mkbIkyePJkvv/ySnJwcXn/9dY4fP86oUaPaNDNaWFhIU1MT7u7ueq+7u7uTm5vb4nuSk5NZs2YNTU1NrF+/nueff54333yTl1566aLXefXVV7G3t9c9fH19W12j0QkYDyYWUJYB+R0bNi1MVfz3hoEAfLc/gx2nW27v6G1cLF1YNmYZP8z5gWHuw6hrquPjYx9zzc/XsPrUahrUvXv2WgghhOgsnb6zl62tLVOmTGHy5Mk4ODhw8mTn3izUvHrCxx9/zNChQ5k/fz7PPvssH3300UXf8/TTT1NWVqZ7ZGRkdGqNncrMShtmocN2+TrfyCBnlowJAOCxH46SV947NkpojT5Offh8+ue8Pelt/Gz9KK4t5qV9L3H9uuvZmraVDlrpTgghhBBndVqQramp4auvvmLSpEmEhoby/fff8+ijj5Kamtrqc7i4uKBSqcjL07+5KC8vDw8Pjxbf4+npSVhYGCqVSvdaREQEubm51NfXt/gec3Nz7Ozs9B7dmq69YEunnP6pmX2I8LSjuKqeh7+PpUktAa2ZQqFgqv9Ufpn3C8+MfAYnCydSy1N5ZOcj3LrhVtnuVgghhOhAHR5k//zzT+6++25dX6yPjw9bt24lKSmJZ599tk2rB5iZmTF06FC2bdume02tVrNt2zZGjx7d4nvGjh1LUlKS3jJgCQkJeHp6YmZmduVfWHfSvF1t+p9QU9Lhp7cwVbHilsFYmanYm1zEiu0ds0JFT2KqNGVBnwX8cd0f3DPwHixNLDlacJQlG5fwj63/IK4oztAlCiGEEN1ehwbZvn37MnbsWA4fPsyrr75KTk4O//vf/5g8efIVn/PRRx/lk08+4csvvyQ+Pp57772XqqoqbrvtNgAWLVrE008/rRt/7733UlxczEMPPURCQgJ//PEHr7zyCvfff3+7v75uwzEAXMK129We2d4plwh2teGlef0BeGdbAn8mF3XKdbo7GzMbHhj8AH9c9wc3ht2IicKEmKwYbv79Zh7d+SjJpcmGLlEIIYTotjo0yE6dOpXDhw9z8OBB7r33Xuzt7dt9zvnz5/PGG2/wwgsvEBkZSWxsLBs3btTdAJaenk5OTo5uvK+vL5s2beLAgQMMHDiQBx98kIceeoinnnqq3bV0K2HNu3x17DJc57t+iA83DPFBrYGHvj/SK3f9ai1XK1eWjl7Kr/N+ZXbQbBQo2JK2het+vY5ndz9LRnk37ssWQgghDEShkTtQLtCWPX6NVko0fDkbrJzh8URQqi7/nitQVdfInBW7SS6oYnK4K58tHo5SqeiUa/UkiSWJvB/7PtvStW0zKoWK2UGzuXvg3fjZ+Rm4OiGEEMJw2pLDOmxGdsiQIZSUtL4fc9y4cWRlZXXU5cVf+Y0CC3uoLoL0ltfc7QjW5ia8f8sQzEyU7DhdwCfR8qvy1gh1DGX55OV8N+s7xnuPp0nTxLoz65j7y1ye3f0s6eXphi5RCCGEMHodNiOrVCrZvn07Tk5OrRo/ZswYjh07RlBQUEdcvkP1iBlZgF/ug9hvYPidMOvNTr3U13+m8fwvJ1Aq4LMlw5kc7tap1+tpjhcc58OjHxKdFQ2AUqFkVuAs7hxwJ0EOxvd3RAghhOgsbclhHRpkFQpFq9fKVCgUJCYmSpDtTIlb4ZsbwNoVHj0FKpNOu5RGo+HJNcf48VAmNuYm/HzfGMLcbTvtej3V8YLjfHTsI6IyowBQoGCK3xTuHHAn/Vz6Gbg6IYQQovMZJMimpaW1+T0+Pj56670aix4TZJsa4I0wqCmGResgaFKnXq6+Uc3fP9vH/pRifJ0s+eW+sTjbmHfqNXuquMI4Pj3+KVvTt+peG+M1hjsH3Mkw92EoFNKHLIQQomcySJDtSXpMkAX49UE4/CUMWQxz3+30yxVX1TPv/RjSi6sZHuDI/+4cibmJ8f2w0l2cKT3DZ8c/Y33Kepo0TQAMdBnIkv5LuMr3KlSddBOfEEIIYSgSZNupRwXZ5J3w1bVg6ahdvUBl2umXTMyr4PoP9lBR18iNQ314/caBMoPYTpkVmayKW8XaxLXUq7U71PnZ+rGo7yKuDbkWCxMLA1cohBBCdAwJsu3Uo4JsUyO81QeqCmDhTxA6tUsuuyuhgNu+2I9ao93S9h8Tg7vkuj1dYU0h3536ju9PfU95fTkAjuaOLOizgJvCb8LZ0tnAFQohhBDtY5Dlt4SRUplA32u1H8f93GWXnRjmytI52puT/rvxFL8dze6ya/dkLpYu/HPwP9ly4xaeGvEU3jbelNSV8MHRD7h6zdU8H/M8p4tPG7pMIYQQokvIjGwLetSMLEBqDKy6Bszt4YkkMDHrsksvXXeCL/emYaJU8NHfhzK1r3uXXbs3aFQ3sjVtK1+f/Jpjhcd0r4/0GMnf+/6dCT4TUCrk51UhhBDdh1G0FpSWlrJmzRrOnDnDE088gZOTE4cPH8bd3R1vb+/OuGSH6XFBVq2Gt/tCRQ4sWA3hM7rw0hoe/SGWX2KzMTNR8sWS4YwNcemy6/cmRwuO8vXJr9matlV3Y5iPjQ8397mZeSHzsDdv/5bRQgghRGczeJA9duwYU6dOxd7entTUVE6fPk1QUBDPPfcc6enpfPXVVx19yQ7V44IswIanYN+HMHA+XP9xl166sUnNfd8cZvPJPKzMVHx9xwiG+rdu4wzRdjmVOXx3+jvWJKyhor4CAAuVBbOCZnFzn5vp49THwBUKIYQQF2fwHtlHH32UJUuWkJiYiIXFubupr7nmGqKiojrjkuJy+l2nfT61Hhpqu/TSJiol790ymPGhLlTXN7HkiwOcyCrr0hp6E08bTx4d+ijb/raNZaOXEe4YTm1TLT8l/sTffvsbt66/ld/O/EZdU52hSxVCCCHapVNmZO3t7Tl8+DDBwcHY2tpy9OhRgoKCSEtLIzw8nNrarg1SbdUjZ2TValg+AMozYf7/IGJOl5dQU9/E4s/3sz+1GCdrM1bfPYpQ2f2r02k0GmILYvku/ju2pG2hUdMIgL25PdcGX8vfwv5GgH2AYYsUQgghzjL4jKy5uTnl5eUXvJ6QkICrq2tnXFJcjlIJ/eZpPz7RdasXnM/STMVnS4Yx0Mee4qp6Fnyyj5PZF36fiI6lUCgY7DaY1ya+xuYbN/NA5AN4WHtQVlfGVye/Ys4vc7hz051sTNlIfVO9ocsVQgghWq1TZmTvvPNOioqK+OGHH3BycuLYsWOoVCrmzZvHhAkTWL58eUdfskP1yBlZgKxD8MlVYGqlXb3AzNogZZRU1bPw032czCnHzsKEL24bLj2zXaxJ3URMdgw/nP6BqMwoNGj/GXAwd2B20GyuD72eUMdQA1cphBCiNzL4zV5lZWXceOONHDx4kIqKCry8vMjNzWX06NGsX78ea2vDBKjW6rFBVqOBdyOhJBVu/AL6X2+wUspqGrhj1QEOppVgYapk5a3DmBgms/WGkF2ZzU+JP/FL0i/kV+frXh/oOpDrQ65nesB0bMxsDFihEEKI3sTgQbbZ7t27OXbsGJWVlQwZMoSpU7tmV6n26rFBFmDrMtj9NoRfAwu+M2gpNfVN/ON/h9iVUICpSsHb8yOZPdDLoDX1Zs2ztD8n/syujF26XlpLE0um+k3l2pBrGe4xXNalFUII0amMJsh2Vz06yBYkwPvDQaGCR+LAztOg5dQ3qnn0h1h+P5aDQgGvXDeABSP8DFqT0G6F++uZX1mbuJbU8lTd657WnswNnsu1wdfia+druAKFEEL0WAYPsu+++27LF1MosLCwICQkhAkTJqBSqTr60h2iRwdZgM9nQvoeuOo5mPCEoauhSa3h+XUn+HZfOgAPTgnl4SmhKJUKA1cmNBoNxwqPsS5pHRtTNlLRUKE7Nsh1EHOC5jAjcIZstiCEEKLDGDzIBgYGUlBQQHV1NY6OjgCUlJRgZWWFjY0N+fn5BAUFsWPHDnx9jW9Wp8cH2aPfw9p7wMEPHjyqXdHAwDQaDa9vOs0HO88AcM0AD9742yCszEwMXJloVttYy46MHaxLWsfenL2oNWoATJQmTPSZyJygOYz3GY+Zquu2QBZCCNHzGDzIfvfdd3z88cd8+umnBAcHA5CUlMQ999zD3XffzdixY7n55pvx8PBgzZo1HX35duvxQbahBt4Mh9oy+PvPEDLF0BXp/HAwg2fXHqehSUM/Lzs+WTQMLwdLQ5cl/qKguoD1Kev57cxvnC45rXvd1tSWaQHTuCbwGoa5D0OlNM7fugghhDBeBg+ywcHB/PTTT0RGRuq9fuTIEW644QaSk5PZs2cPN9xwAzk5OR19+Xbr8UEWYP2TsH8lRMyF+V8buho9B1OLuefrQxRV1eNiY87KW4cy1N/R0GWJi0goSeD3M7/zR8ofeqseuFq6MiNwBtcEXkM/534oFNIqIoQQ4vIMHmStrKyIiopi2LBheq8fOHCAiRMnUl1dTWpqKv3796eysrKjL99uvSLI5sXBh2NAaQKPxoONm6Er0pNZUs2dXx7kVG4FZiolr1w/gBuH+hi6LHEJao2aQ3mHWJ+yns2pmymvP7fZhY+NDzMCZzAjYAZhjmESaoUQQlyUwYPsrFmzyM3N5dNPP2Xw4MGAdjb2rrvuwsPDg99//53ffvuNZ555huPHj3f05dutVwRZgE+mQNZBmPoijHvY0NVcoKqukUdWx7L5ZB4Afxvqw4vX9pO+2W6gvqmemKwY1qesZ1fmLmoaa3THAuwCmBE4g+n+0wlxDDFglUIIIYyRwYNsbm4ut956K9u2bcPU1BSAxsZGpkyZwtdff427uzs7duygoaGBq6++uqMv3269Jsge/hp+fQCcguCfh8EIZ8nUag3vbU/inW0JqDUQ4mbDilsG08ejB/936WGqG6qJyoxiY+pGojOjqVef2wY3yD6IqwOu5mr/qwlxCJGZWiGEEIYPss1OnTpFQkICAOHh4YSHh3fWpTpUrwmy9VXwRjjUV8Di3yBwgqEruqg/k4t46Psj5JXXYW6i5PnZfVk40k+CTzdTWV/JjowdbE7dTEx2DA3qBt2xQPtApvlPY5r/NMIdw+W/rRBC9FJGE2S7q14TZAF+exgOfQH9b4QbPzN0NZdUVFnH4z8eZcfpAkC7RNer1w3E3srUwJWJK1FRX8HOjJ1sTttMTJZ+qPWx8WGq/1Sm+k9lgMsA2U1MCCF6EaMIspmZmfz666+kp6dTX1+vd+ytt97qjEt2mF4VZLNj4eOJoDKDR0+BtbOhK7oktVrD5zEp/HfjKRqaNLjZmvPKdQOY2tfd0KWJdmgOtdvStxGTFUNtU63umJuVG5N9JzPFbwrDPIZhqpQfXIQQoiczeJDdtm0bc+fOJSgoiFOnTtG/f39SU1PRaDQMGTKE7du3d/QlO1SvCrIAKydAzlGY/gqMvt/Q1bTK0YxSHvkhluSCKgDmRXqxdE4/HK1lMf7urrqhmpjsGLakbSEqM4qqhirdMTszOyb6TGSK3xRGe43GytTKgJUKIYToDAYPsiNGjGDmzJm8+OKL2NracvToUdzc3Fi4cCEzZszg3nvv7ehLdqheF2QPfAZ/PAou4XD/PqO86asltQ1NvL01gU+iklFrwMXGnJfm9WNGf09DlyY6SF1THfty9rEtfRs7M3ZSXFusO2auMme052gm+01mos9EnC2N+7cJQgghWsfgQdbW1pbY2FiCg4NxdHRk9+7d9OvXj6NHj3LttdeSmpra0ZfsUL0uyNaWa3f6aqiGResgaJKhK2qT2IxSnvjxKIn52jWJZw3w5PnZffGwtzBwZaIjNambiC2IZVv6NranbyerMkt3TIGCQa6DmOw3mcm+kwm0DzRgpUIIIdqjLTmsU+6gsLa21vXFenp6cubMGd2xwsLCzrikaA8LO4hcqP045h3D1nIFIn0d+P3Bcdw/ORiVUsEfx3O46s2dfLTrDPWNakOXJzqISqliqPtQnhz+JBuu38CaOWu4P/J++jr3RYOG2IJY3j70NnN/mcuctXN48+CbHMw9SKO60dClCyGE6CSdMiM7b948Zs2axV133cXjjz/OunXrWLJkCT///DOOjo5s3bq1oy/ZoXrdjCxASSq8OwQ0TXBPFHgOMnRFV+REVhkvrDvB4fRSAIJcrXlxbj/Gh7oatjDRqXKrctmZsZMdGTvYn7tfL7zam9sz3ns8E30nMtZrLLZmtoYrVAghxGUZvLUgOTmZyspKBg4cSFVVFY899hh79uwhNDSUt956C39//46+ZIfqlUEWYM0dcGJNt1iK61LUag0/H8ni/zbEU1ip/c3AjH4ePDsrAl8nuTmop6usr2RP9h52ZuwkKiuKsroy3TEThQlDPYYy0Wcik3wm4Wvna7hChRBCtMjgQba767VBNueodgUDhRIePAKOAYauqF3Kaxt4e0sCX+1No0mtwVSl4O+j/PnnVaE4yeoGvUKjupHY/Fh2Ze5iV+YuUspS9I4H2QcxwWcCE3wmEOkWKUt7CSGEETB4kA0KCuLAgQM4O+vfRVxaWsqQIUNITk7u6Et2qF4bZAG+vg7ObIfhd8GsNwxdTYc4lVvOS7/HsztJ259tY27CPyYGcfu4QKzMTAxcnehK6eXp2pnazCgO5R2iUXOuBcHWzJZxXuMY7zOecd7jcLRwNFyhQgjRixk8yCqVSnJzc3Fzc9N7PS8vDz8/P+rq6jr6kh2qVwfZ5F3w1VwwsYRHToC1i6Er6jDRiQX834ZTxGWXA+Bqa85DU0K5aZgvZiayc1RvU15fzp7sPURnRhOdGU1JXYnumFKhZKDLQN1sbZhjmGyZK4QQXcRgQfbXX38FtDd7ffnll9jb2+uONTU1sW3bNrZs2cLp06c76pKdolcHWY0GPpkM2Udg4r9g8jOGrqhDqdUafjuWzRubT5NRXAOAl70F904O4aZhPpibqAxcoTCEJnUTxwuPE5UZRVRmFKdL9P+NcrdyZ7zPeCZ4T2Ck50jZiEEIITqRwYKsUqmd1VIoFPz1tKampgQEBPDmm28ye/bsjrpkp+jVQRYgbi38uAQsHeGRODCzNnRFHa6+Uc23+9L4YOcZ8iu0vyHwsLPg3knBzB/ui4WpBNreLLcql6jMKKIzo/kz50+9LXPNlGYM9xiuDbY+E/C1lRvGhBCiIxm8tSAwMJADBw7g4tI9fy3d64OsuglWDIPiZJjxfzDKuHdia4/ahiZWH8jgw51nyC3XhhU3W3PuGh/EzSN8sbWQm396u9rGWg7kHtAG26xovY0YAALtAxnvrQ21Q9yGYKqS7xkhhGgPgwfZ7q7XB1mAg5/D74+Ava92BYMe/j/n2oYmfjyYwQc7z5BTpg20tuYm3DLSj9vGBsouYQIAjUZDclky0ZnRRGVFcSTviN4NY9am1ozxGsN47/GM9xmPi2X3/GFeCCEMySBB9t1332312AcffLAjLtlpJMgCDTWwfABUFcB1H8Og+YauqEvUNTax9nAWn0Qnc6agCgATpYK5kV7cNT6ICM9e+v0gWlRRX8Ge7D1EZUaxO2s3xbXFesf7OffT9db2c+mHUiE3FQohxOUYJMgGBrZub3OFQiHLb3UXUW/A9v+Acwjc92ePn5U9n1qtYcfpfD6OSmZfyrlwMirIicWjA5jW1x0TlYQScY5aoyauMI6oLO0NYyeLTuodd7JwYpz3OCb6TGSM1xhszGwMVKkQQhg3aS1oJwmyZ9WWw7uRUF0Es96C4XcYuiKDiM0o5ZPoZDaeyKVJrf3r4mlvwcKRftw8wg8XG3MDVyiMUWFNoXZpr6xo9mTvoaqhSnfMRGHCUPehjPcZz0SfiQTYBxiuUCGEMDJGFWSbT9+d1mCUIHuefSthw5Ng7abtlTXvvbNIOWU1fLsvne/2p+u2vjVTKZnR34Obh/syKsgZpbL7fJ+LrtPQ1MDh/MO65b1Sy1P1jvvb+evWrB3qNlRuGBNC9GpGEWS/+uorXn/9dRITEwEICwvjiSee4NZbb+2My3UoCbLnaayH90dASQpMehomPWXoigyurrGJDcdz+XJvKkfSS3Wv+ztbMX+4LzcO9cHNVm4OExeXXp5OVGYUuzJ3cTDvII3qC28Ym+gzkfE+43GycDJgpUII0fUMHmTfeustnn/+eR544AHGjh0LwO7du3n//fd56aWXeOSRRzr6kh1KguxfNK8ra2qtnZW1dTd0RUbjRFYZ3+1PZ11sNpV12jBiolQwJcKNG4f6MincFVPppRWXUNVQxd7svezK3EVUZpTeDWMKFAxyHcRE34lM9JlIiENIt/rtlhBCXAmDB9nAwEBefPFFFi1apPf6l19+ybJly0hJSenoS3YoCbJ/odHAp1Mg6xAMuwNmv2XoioxOdX0jvx/L4fv96Rw+b5bW2dqMuZFe3DjUh35e9hc/gRBobxg7WXSSnRk7icqMIr44Xu+4t403E30mMtF3IsPdh0sLghCiRzJ4kLWwsODEiROEhITovZ6YmMiAAQOora29yDuNgwTZFqTuhlWzQKGC+/eBS6ihKzJap3Mr+PFgBr/EZlNYWad7vY+HLdcP8WbuIG9Zl1a0SvMOY7syd7EvZx91Tee+n6xNrRnrNZZJvpMY7z0eBwsHwxUqhBAdyOBBtn///txyyy0888wzeq+/9NJLrF69muPHj3f0JTuUBNmL+HY+JGyEPrPh5m8MXY3Ra2xSE5VYwE+HsthyMo/6JjUACgWMDHRiXqQ3M/t7Ym8ls2ri8moaa/gz+092Ze5iZ8ZOimqLdMdUChWD3QYzyXcSV/leha+dbJsrhOi+DB5kf/rpJ+bPn8/UqVN1PbIxMTFs27aNH374geuuu66jL9mhJMheRH48fDgGNGq4fTP4jTR0Rd1GWXUDvx3L5tfYbPannuuBNFUpmBTuxuyBnkyNcMfa3MSAVYruonnN2p2ZO9mRsYPEkkS948H2wUz2m8xk38n0d+kvGzEIIboVgwXZEydO0L9/fwAOHTrE22+/TXy8tscrIiKCxx57jMGDB3fU5TqNBNlLWPcAHPkafEfC7Zu004uiTTJLqvntaA7rYrM4lVuhe93cRMlVfdyYPdCLyX1csTKTUCtaJ7Mik12Zu9iRvoODeQdp0jTpjrlaujLZdzKT/SYzwmMEZiozA1YqhBCXZ7Agq1QqGT58OHfeeSc333wztra2HXXqLiVB9hLKs+HdIdBYA9d/CgP/ZuiKurXTuRX8djSb349lk1pUrXvd0lTFVX3cmNHfg8l93LCRmVrRSmV1ZezO2s2OjB1EZ0ZT3Xju+8ra1Jrx3uOZ4jeFcd7jZHcxIYRRMliQjY6O5osvvmDNmjWo1WpuvPFG7rjjDsaPH99Rl+gSEmQvY9frsOMlsHKG+w+AtbOhK+r2NBoNcdnl/HE8hz+O5ZBefC58mJkomRDqysz+HkyNcJeeWtFq9U317M/dz/b07ezM2ElBTYHumKnSlJGeI5niN4VJvpNwsXQxXKFCCHEeg/fIVlVV8cMPP7Bq1Sqio6MJCQnhjjvuYPHixXh4eHT05TqcBNnLaKyHjydC/kkYOB+u/9jQFfUoGo2G41llbDiRy8YTuaQUnre1qVLB6GBnru7rzrS+HrL6gWg1tUbN8cLjbE/fzvb07Xq7iylQMNhtMFP9pzLFbwpeNl6GK1QI0esZPMieLykpiS+++IKvv/6a3NxcZsyYwa+//tqZl2w3CbKtkHkQPp0KaGDhTxA61dAV9UgajYbTeRVsOK4NtafzKvSOD/J14Oq+7kzv506wq40sli9aRaPRkFKWwrb0bWxL30ZcUZze8b7OfZnqN5Wp/lMJtA80UJVCiN7KqIIsaGdov/nmG55++mlKS0tpamq6/JvO8/777/P666+Tm5vLoEGDeO+99xgxYsRl3/f999+zYMECrr32Wn755ZdWX0+CbCttfBr+/ADsfeG+vWDePXuiu5Pkgkq2nMxjU1yu3sYLAAHOVkyNcGdKhDvDAxwxkR3FRCvlVOawPWM7W9O2cjj/MGqNWncs2D6YaQHTmOo3lTDHMPlhSQjR6YwmyEZFRfH555/z008/oVQquemmm7jjjjsYNWpUq8+xevVqFi1axEcffcTIkSNZvnw5P/74I6dPn8bNze2i70tNTWXcuHEEBQXh5OQkQbYz1FfBB6OgNB1G3APXvGboinqV/PJatsbnsykul71ninTr1ALYW5oyOdyVKRHuTAhzxd5S+mpF6xTVFLEzYydb07fyZ86fNKobdcf8bP2Y6j+Vq/2vpq9zXwm1QohOYdAgm52dzapVq1i1ahVJSUmMGTOGO+64g5tuuglra+s2n2/kyJEMHz6cFStWAKBWq/H19eWf//wnTz31VIvvaWpqYsKECdx+++1ER0dTWloqQbazJG2D/10PKOCOzeB7+Zly0fEq6xqJTihgS3weO07lU1LdoDumUioYHuDIlD7uXBXhRpCLtQQQ0Srl9eXsytjFlrQtxGTFUK+u1x3ztvFmmv80rva/mv4u/eV7SgjRYQwWZGfOnMnWrVtxcXFh0aJF3H777YSHh1/x+err67GysmLNmjXMmzdP9/rixYspLS1l3bp1Lb5v6dKlHDt2jLVr17JkyZLLBtm6ujrq6s5t/VheXo6vr68E2dZaey8c/RZcwuEf0WBibuiKerUmtYbD6SVsPZnHtlP5JOVX6h0PcLZiUrgbk/u4MTLQCQtTlYEqFd1JdUM1UVlRbEndQnRWNDWNNbpjntaeTPOfxvSA6QxwGSChVgjRLm0Jsh26OKWpqSlr1qxh9uzZqFTt/59jYWEhTU1NuLu7673u7u7OqVOnWnzP7t27+eyzz4iNjW31dV599VVefPHF9pTau01/GZK2QOFpiHoDrnrW0BX1atoZWCeGBzjx9DURpBVVsf1UPttP5fNnchGpRdWs2pPKqj2pWJqqGBvizKRwNyaFu+LjaGXo8oWRsjK1YkbADGYEzKCmsYbdWbvZnLqZXZm7yKnK4auTX/HVya/wsvbShVqZqRVCdLYuudnrSmVnZ+Pt7c2ePXsYPXq07vUnn3ySXbt2sW/fPr3xFRUVDBw4kA8++ICZM2cCyIxsVznxM6y5DRRKWLQOAicYuiLRgsq6RnYnFrLzdD47TueTV16ndzzEzYZJYa5MCndjeKAj5iYyWysurbaxlpisGDalbWJnxk69mVovay+mB0xneuB0+jpJT60QonWM5mav9mpra0FsbCyDBw/Wmw1Wq7U3wCiVSk6fPk1wcPBlrys9slfol/sg9huwdtO2GNga/5rBvZlGoyE+p4Idp/PZcSqfw+klqM/718DSVMWYYGcmhrsyIdSVAJe297iL3kUXalM3sTNTP9T62voyPWA6MwJmyOoHQohL6jFBFrQ3e40YMYL33nsP0AZTPz8/HnjggQtu9qqtrSUpKUnvteeee46KigreeecdwsLCMDO7/D7jEmSvUH21dm3Z/DjwHwuLfgWVbK3aXZRVN7A7STtbuyuhgPwK/dlaf2crJoS6MiHMlTHBzljLtrniEmoba4nOimZT6iaiMqP0Qm2AXQAzA2cyI2AGQQ5BBqxSCGGMelSQXb16NYsXL2blypWMGDGC5cuX88MPP3Dq1Cnc3d1ZtGgR3t7evPrqqy2+vzWtBX8lQbYdCpPg40lQXwHjHoGpywxdkbgCzbO1uxIKiEoo4GBaMQ1N5/6pMFUpGOLnyIQwV8aHutDfyx6lUmbYRMuabxTblLKJ6Kxo6prO/ZAU5him6731tfM1YJVCCGPRo4IswIoVK3QbIkRGRvLuu+8ycuRIACZNmkRAQACrVq1q8b0SZA0gbi38uET78YLVED7DoOWI9qusa+TPM0XsSihgV0IB6cXVescdrUwZG+LC+FAXxoW64u1gaaBKhbGraqhiR8YONqZsJCY7Rm+d2v7O/ZkZOJPpAdNxt3a/xFmEED1ZjwuyXU2CbAdY/yTsXwkWDnBPFDj6G7oi0YHSiqqISiwkOqGAvWeKqKhr1Dse5GLNuFAXxoW4MDrYGVsL2ZBBXKisrozt6dvZkLKBfbn7dDuKKVAwxH0I1wRew1T/qThZOBm4UiFEV5Ig204SZDtAYz18MROyDoLXYLh9k6wv20M1NKk5mlFKVGIhuxMLiM0o1btpTKVUMMjHnnEh2tnaSF8HzExk+1yhr6imiC1pW9iQsoHD+Yd1r6sUKkZ5jeKawGu4yvcqbMxsDFilEKIrSJBtJwmyHaQ0A1aOh5oS6Hcd3PA5KCXA9HRlNQ3sPVPE7qQCdicWklqk34ZgZaZiZKATY0NcGBPsQh8PW+mvFXpyq3LZmLKR9SnriS+O171urjJngs8EZgbOZILPBMxV8sOxED2RBNl2kiDbgZJ3wv9uBHUDjLgbZr4GsuxOr5JRXM2eM4XsTipiT1IhRVX1esedrM0YHezM2GAXxoY44+dkJUszCZ3UslQ2pGxgfcp6UstTda/bmNpwld9VXBN4DSM9R2KilFU0hOgpJMi2kwTZDnbiJ1hzB6CBq56DCU8YuiJhIGq1htN5FexOLCTmTCH7U4qprm/SG+PtYKkNtiHOjA5ywcPewkDVCmOi0Wg4VXyKDSkb2JC6gdyqXN0xJwsnrva/mllBsxjkOkh+EBKim5Mg204SZDvBvpWw4Untx3PehaGLDVuPMAr1jWqOZpYSk1TInqQijmSU6C3zBRDkas3oIGdGBzszKsgZFxv5dXJvp9aoic2PZX3KejanbqakrkR3zMvai5mBM5kZOFM2XhCim5Ig204SZDvJtn9D9JvabWxv+hoiZhu6ImFkqusbOZhawp4zRew9U8jxrDK9G8cAwt1tdaF2ZKATjtaX3+RE9FwN6gb25exjffJ6tqVvo7rxXE92iEOILtT62soatUJ0FxJk20mCbCfRaODXf8KRr0FlDreuhYCxhq5KGLGymgb2JRexN7mIvWeKOJVboXdcoYA+HnaMCnJidJAzIwOdsbeSpb56q9rGWqIyo1ifsp6ozCga1A26YwNdBnJN0DVMD5iOi6WLAasUQlyOBNl2kiDbiZoa4Ydb4fR6MLWGBd9C0CRDVyW6iaLKOvalFLP3TBF/JheRmF+pd1yhgAgPO0YGOelmbB2sZMa2NyqvL2db2jb+SPmDA7kHdGvUKhVKRniM4JrAa5jiPwU7M/k3XghjI0G2nSTIdrKGGvjuZu2KBiozuOEz6DvX0FWJbqigoo59KdpQ+2dyMUl/CbYAfTxsdaF2RKATztJj2+sU1hSyKXUT65PXc6zwmO51U6Up47zHcU3gNUz0nYiliexIJ4QxkCDbThJku0BjHfx0J8T/qu2Znb1cbgAT7ZZfUcv+lOJLBttQNxtGBDox8my4dbeTVRF6k4zyDDakbmBDygaSSpN0r1uaWDLZdzIzA2cy1msspippURHCUCTItpME2S6iboLfH4HDX2o/n/oijHvYoCWJnqWgoo79KcXsSyliX3Ixp/MqLhgT4GzFiEAnRgRqg62Po6Xc6d5LJJQkaJfzStlAVmWW7nVbM1um+U9jRsAMhnsMlzVqhehiEmTbSYJsF9JoYNuLsPtt7edjHoRp/5ZNE0SnKK6q50BqMfuSteE2Pqf8glURPO0tGB6gbUMYGehEiJuNBNseTqPRcLzwOBtSNrApdRMFNQW6Y81r1M4InMFgt8EoFbI7oRCdTYJsO0mQNYCYd2HL89qPI+bAtR+AhfzZi85VXtvAobQS9iUXsz+liGOZZTT+Jdk6Wpnqgu3wACf6edlhopIw01M1qZs4nH+YDSkb2JK2hdK6Ut0xNys3Xagd6DJQfsARopNIkG0nCbIGcuQb+P1haKoHp2CY/zW49zN0VaIXqalv4kh6CftTi9mfUszh9BJqG9R6Y6zMVAzxc2R4gBPDAx0Z7OuIpZnKQBWLztSgbuDP7D/ZmLqR7enbqWw413PtZe3F1QFXMz1gOv2c+0moFaIDSZBtJwmyBpR5CH5cDGUZYGIJc96BQfMNXZXopeob1ZzILmN/SjEHUoo5kFpMeW2j3hgTpYL+3vaMCHRimL824MomDT1PfVM9MVkxbEzdyM6MnXobL3jbeHO1/9VcHXC1hFohOoAE2XaSIGtgVUXw851wZrv282F3wIxXwUSWTRKGpVZrSMiv4EBKMftTSziQUkxuee0F40LcbLQztgHaYCs3kPUstY21RGdFszl1M7syd1HTWKM75m3jzVS/qUwLmMYAlwHSUyvEFZAg204SZI2Augl2vQa7/gtowGMgzPsAPAYYujIhdDQaDZklNRxILeZAagkHUlte8svDzoLhgdpgO8zfiXAPW1RKCbY9QU1jDbuzdrcYat2t3JnqP5Vp/tOIdI1EpZQWFCFaQ4JsO0mQNSKJW+Dnu6CmBJQmMPYhmPAkmMran8I4FVfVczC1mINpJexPKeZE1oU3kNmamzDE31EbbAOciPR1wMJUQk531xxqt6RtYVfGLr32A2cLZyb7TWaK3xRGeoyUdWqFuAQJsu0kQdbIVOTC+ie0mycAOIfC3PfAf7Rh6xKiFWrqm4jNKD07a1vM4bQSquqb9MaYqrR9tsMDtH22wwKccJI+226trqmOvdl72ZK2hR0ZO6ioP7eGsa2pLeN9xjPFbwpjvcdibWptwEqFMD4SZNtJgqyROvkrrH8cKvO0nw+/E656HiwdDFqWEG3R2KTmVG4FB89rR8ivqLtgnLbPVtuKMDzACV8n6bPtrhqaGjiQe4Bt6dvYnrGdwppC3TFTpSkjPUcy2Xcyk3wn4WblZsBKhTAOEmTbSYKsEaspgc3Pw5GvtZ9bOsL4x2HEXXIzmOiW/tpnezC1mMQW+mzd7cwZFuDEcH9Hhgc60cfDTvpsuyG1Rs2xgmNsS9/GtvRtZFRk6B3v79yfyX6TmegzkTDHMPnhRfRKEmTbSYJsN5C8CzY8CQWntJ/b+8FVz8KAv4HcUCG6uZKqeg6mlZydtS3meFYZDU36/1TbnO2zHSF9tt2WRqMhuSyZHRk72JGxg2MFx/SOu1u5M8FnAhN9JjLCcwSWJpYGqlSIriVBtp0kyHYTTY1w9DvY8QpUZGtfc++vbTcImy7b3Ioeo7ZB22d7MFW77NfhtBIq6/TXszVTKRngY69b9muYvxP2VnJDUXdSWFPIzoyd7Mrcxb6cfXorIJirzBnmPoxx3uMY6z2WALsAma0VPZYE2XaSINvNNNTAvpUQ/RbUlWlfc42A0ffDwJuk5UD0OE1qDadyy89u0tByn61CAeHutrqtdUcEOuFuJ6t9dBd1TXUcyD3AroxdRGVGkV2VrXfc28abcd7jGOM1hhEeI7AxszFQpUJ0PAmy7SRBtpuqLoaY5XDgc2i+Q9jGHUbcDcNuBysng5YnRGfRaDSkF1drQ+3ZHciSC6suGOfnZMWIQG2oHRnohJ+TlczqdQMajYYzpWeIyY5hd9ZuDuUdokHdoDuuUqgY4DKA0V6jGe01mv4u/TFVymy86L4kyLaTBNlurrYMDn0Jf354ruXA1Ar6Xw+DbwXfkdJ2IHq8goq6s60IxexPKSY+p5y/LGeLu505IwKddcE21M1Ggm03UN1QzYHcA0RnRfNnzp+klafpHbc2tWao+1BGeIxguMdwwh3DZTMG0a1IkG0nCbI9RFMDxK2FPe9C7vFzrzuHQORCGLQA7DwNV58QXai8toFDadoZ2/0pxRzNLL3gBjInazNGnG1DGBkkKyN0F1mVWfyZ/Sd7c/ayL2cfpXWlesdtzWwZ5j6M4R7DGeo+VIKtMHoSZNtJgmwPo9FA+l448j+I+wUazv7KVaGEoMnQbx6EzwJrZ0NWKUSXqm1o4kh6KftSijiQWsyhtBJqG9R6Y+wsTBgR6MSoIGdGBjrT10uCrbFTa9ScKj7FgdwD7M/dz6G8Q1Q16LeZWJtaE+kayRD3IQxxG0J/l/5YmEj/tDAeEmTbSYJsD1ZXoQ2zsd9ow20zhQoCxkLEXIiYA7YeBitRCEOob1RzPKuMfSlF7Esu5mBq8QU7kNmamzA80IlRQU6MDnKRYNsNNKobiS+K14XaI/lHqGzQX6fYRGFCuFM4g1wHaR9ug/Cy9pI2E2EwEmTbSYJsL1GYpG09iF+n33qAArwiIXgKhEwFn2Eg+6KLXqaxSU1cdjn7Uor4M7mYAynFVPxlyS9bCxNGBDgxOtiZUUHORHhKsDV2TeomEksTOZR3iMN5hzmcf1hvp7FmzhbO9HfpTz+XfvR37k9/l/44WjgaoGLRG0mQbScJsr1QcQrE/wbxv0LmAf1j5nYQOAGCr4KAceASJjeLiV6nSa3hZHY5fyYX8WdyEftbCLb2lqaMDHRiTLAzo4NdCHOXm8eMnUajIbsqm6P5RzlaoH2cLj5No6bxgrFe1l70de5LH6c+uoeblZv8NxYdToJsO0mQ7eXKc+DMdjizDc7sgJpi/eNWLuA/Rhtq/ceAW1/ZTUz0Ok1qDXHZZfyZXMTeM0UcSL1wkwYXGzNGBTkzNsSFMcHOstxXN1HbWMup4lOcKDzBiaITxBXGkVqe2uJYJwsnwh3DCXUM1T2C7YOl51a0iwTZdpIgK3TUTZATC0nbIWWXdra2sVZ/jJkteA8Gn+HgPUzbimDjZpByhTCUxiZtj+2eM9oZ2wOpxRfcPObtYMmY4LPBNsQZN1sJO91FRX0FJ4tOcqr4lO6RXJaMWqO+YKxSocTP1o8QhxAC7QMJcggiyD6IQPtA2WZXtIoE2XaSICsuqrEOso9AWgyk7YH0P6G+8sJx9n7gNQg8I7X9tp6RYO3SxcUKYTh1jU3Eppey54x2xvZIRskFy32Fu9syNsSFsSHOjAxyxsbcxEDViitR21hLYkkip0tOk1iSSGJpIokliRcs/9VMgQIvGy/87fwJsAvQPtsHEGAXgIe1B0qFsmu/AGG0JMi2kwRZ0WrqJig4pZ2pzTyofRScAlr4a2XnA54Dwb0/ePTXPjsGglL+8RY9X3V9IwdSS9iTVEjMmULisss5//8+JkoFkb4OjAt1YXyoCwN9HDBVyd+N7kaj0VBUW0RCSQLJpckklyVzpvQMKWUplNSVXPR9ZkozfG198bXzxc/WDz9bP+3ntr542HjITmW9jATZdpIgK9qltlzbjpAdCzlHtR8XJbU81swG3Ptp+2x1z33BUu4OFj1bcVU9e88UsTupkD1nCkkrqtY7bmNuwqggZ8afDbaBLtbSX9vNFdcWk1KWQlp5GqnlqaSWpZJWnkZ6RTqN6gtvLmumUqjwtPbEx9ZHF259bH3wsdF+bmNm04VfhegKEmTbSYKs6HC15ZB7DHJPQN5x7XN+PDTVtTze1ksbaF37aMOtWwS4hoOZddfWLUQXySiuZndSIbsTtTO2pdUNese9HSyZEObCuBBXxoY442BlZqBKRUdrVDeSW5VLekU6GeUZpFek6z7OrMyk7mL/Tp7lYO6gC7U+tj742Z2bzXW1dJUfgLohCbLtJEFWdImmRihKhLw47SP/JOSdhLL0i7xBAY4B2lDrFgGuZ59dQsHEvCsrF6JTNS/1FZ1UwO7EQg6mllDfdO6mIoUCBvo4MDHUhQlhrkT6OmAibQg9klqjprCmkIyKDN0jsyKTzMpMMisyKa4tvuT7LU0s8bP1w9/OX9eT62/nT5B9ELZmtl30VYi2kiDbThJkhUHVlmlna3WPk9pHdVHL4xUqcA4+b/a2jzbkOgfLRg6iR6iub2RfSjHRCYXsTiogIU//BktbCxPGBmtD7YQwF3wcrQxUqehq1Q3VunB7fthNr0gnpyqnxVUVmrlZuRFsH0ywg/YR4hBCmGMYVqby/WNoEmTbSYKsMEqVBdpAW3BKG3ALTmk/ry1rebzSVLt5Q/MMbnOLgoO/3GAmurXcslqiEguISihgd9KFbQjBrtZMDHNjYrgrIwOdsDCVdZ57o4amBrIqs3Q9uWnladqPy1LJr8lv8T1KhZIAuwD6OPXRbf7Qz7mf9OF2MQmy7SRBVnQbGg1U5ELB+bO3p7Qht6VlwQBMrbSzt+59wa3f2ee+svat6Jaa1BqOZ5URlaANtofTS1Cf9381cxMlo4KcmRjmyqRwV7lpTADadXHPlJ4huSyZpNIkzpSeIaEkocXtepUKJaEOoUS6RTLYbTBD3IbgaeNpgKp7Dwmy7SRBVnR7ajWUZZybtW0OuQUJF7/BzNr17KoJ/bUrKDTfbGYqC5iL7qOsuoGYM4VEJRSwK6GAnDL9DUz8nKx0oXZ0sDNWZrJ2rTinsKaQ+KJ44ovjOVV8irjCOLKrsi8Y52HtwRivMYz1Gssor1HYmUlW6EgSZNtJgqzosZoaoSTlvJvLzj4Xp9Di2rcKJTiHnAu3HgO0z3be2jtuhDBiGo2GxPxKdp0uYGdCPvtTivU2ZTAzUTIy0IlJ4W5MCnclSGZrRQsKqgs4kn+EI/lHiM2P5VTxKRo155YLUylUDHAZwFjvsUzynUS4Y7h8H7WTBNl2kiArep36am17Qt7ZcJt3Qvtcc5E7gi0dz27sMODcBg+ufWT1BGHUquoa2XOmiJ2n89l5uoCs0hq9475OlkwOd2NyuBujgpyxNJPeWnGh6oZqjuQfISY7hpisGJLLkvWOB9gFMDNwJjMCZxBkH2SgKrs3CbLtJEFWCM713+qC7dlwW5gALS1erjTRhlmPAeAx8Oxzf9ncQRgljUbDmYJKdp4uYOfpAvalFOnN1jb31k4Od2VSuBsBLrKGs2hZTmUOMdkxRGdGsztrN/Xqet2xcMdwZgTOYF7IPFwsZZvy1pIg204SZIW4hMY6be9t7gnIPa4NuLnHLr56goPf2WA7ULtFr8cAaU0QRudys7WBLtZMCndlcrgbI2QlBHERlfWV7MjYwcbUjezJ2qNrQTBRmnC1/9Us6LOAQa6DpPXgMiTItpMEWSHaSKPR3lyWezbU5h7XPpdeZHMHS6ezoXYgeA7SPpyCZVkwYRSae2t3ns5nx6kCDqQW03jeUgiWpirGhjgzKdyNyX3c8HaQGyLFhcrqytiatpW1SWs5WnBU93qEUwQL+ixgZuBMLEwsDFih8ZIg204SZIXoIDUl58JtztmAW3AKNE0XjjW11s7Wep4Ntx4Dz/bdylakwrAqahuISSpkx6kCdpzOJ79Cf+WPcHdbJvXRztYO9XfEVHYZE39xsugk3536jvXJ63WtB84Wztw18C7+FvY3zFTy79z5JMi2kwRZITpRQ612pYTmcJtzVNt721hz4ViVmXZJsOZw6xmpXTVBlgQTBqLRaDiZU86OU9oWhL+uW2trbsL4MBftSghhrrjZyYybOKe0tpSfk35m9anVumW9PKw9uGfgPVwbci2mStmNESTItpsEWSG6WFMjFCWdDbdHzz6OQV0LfbcKlXbHsuaWhOa+Wwv7rq9b9Hql1fVEJRay81Q+OxMKKK6q1zvez8uOyWeX94r0dcBEZmsF0KBuYG3iWlYeW0l+tXaXMV9bX+4ddC+zgmahVPTu7xMJsu0kQVYII6DRQEmqNtSeH3CrCloe7xh4Lth6DgKPQWDj2qUli96tSa3hWGapdiWEhAKOZZZy/v9h7S1NGR+qna2dGOaKq60sV9fb1TXV8cPpH/j0+KcU12qXOxzkOoilo5cS6hhq4OoMR4JsO0mQFcJINS8Jphduj0HZRW4qs/U8t1pCc9+tg5+smCC6RGFlHVEJBew4rd0+t6ymQe94f287JoXJbK3Qrk377alv+fT4p1Q1VGGiMOG2/rdxz6B7MFf1vh94JMi2kwRZIbqZ6mJtsM2OPdd7W5REi7uVWTicvals0Ln1bl3CQCVblYrO09ik5mjzbO3pAo5n6bfN2FmYMD7UlYlhrkwIc8XDXnpre6Pcqlxe3vcyOzN2AuBv58/S0UsZ7jHcoHV1NQmy7SRBVogeoK5Su8Zt86xt7jHIjwd1w4VjVebg3ld/Mwf3fmBu2/V1i14hv6KWqIRCdiUUEJ1YQGm1/vdluLstE8JcmBDmyvAAWbe2N9FoNGxL38Yr+16hoEbbSnVD6A38a8S/sDTpHTe6SpBtJwmyQvRQjfVnN3M4bzmw3ONQX9HyeKegs+F2ALif3alMNnMQHexyvbUWpkpGBjozIcyV8aEuhLrZyIL6vUBFfQXvHH6H1adXAxDqGMrbk97G387fwJV1Pgmy7SRBVoheRK2G0tRzs7bNO5ZVZLc8vrk1wb2/Nti699eud2sqvwoWHaOkqp7dSYVEJRQQlVhAXrn+urXuduaMD9WG2rEhLrjY9L4eyt7kQO4Bntj1BEW1RdiY2vCfsf9hqv9UQ5fVqXpckH3//fd5/fXXyc3NZdCgQbz33nuMGDGixbGffPIJX331FSdOnABg6NChvPLKKxcd3xIJskIIqgrP24L3uDbgFp4GdeOFYxUqcAnVtiO499OGW/d+Mnsr2k2j0ZCQV0lUQgHRSYXsSy6irlGtNybC046xwc6MDXVhRIAT1ubS793TFFQX8PiuxzmcfxiAxX0X89DQh3rsurM9KsiuXr2aRYsW8dFHHzFy5EiWL1/Ojz/+yOnTp3Fzc7tg/MKFCxk7dixjxozBwsKC//73v6xdu5a4uDi8vb1bdU0JskKIFjXWnW1NOHEu4Oad0O5g1hILe3BrDrd9tR+7RYCF/LsirkxtQxMHU0uITiwgKrGQ+JxyveOmKgWDfR0ZE+LMmGAXIn0dMDOR1RB6ggZ1A+8efpdVcasAGOI2hDcnvYmLpYthC+sEPSrIjhw5kuHDh7NixQoA1Go1vr6+/POf/+Spp5667PubmppwdHRkxYoVLFq0qFXXlCArhGg1jQYqcrS7k+Wd0Ibc/JNQmNDy7C1olwBzaw63Zx8uoaDqmbMrovMUVtax90wRMUmFRCcWklWqv0OehamS4QFOjApyZnSwMwO87WUL3W5ua9pWnot5jqqGKnxsfPjk6k/wsfUxdFkdqscE2fr6eqysrFizZg3z5s3Tvb548WJKS0tZt27dZc9RUVGBm5sbP/74I7Nnz25xTF1dHXV153qQysvL8fX1lSArhLhyjXXaMJt3Uhtw8+K0Abcip+XxSlNtmHWLOPvoq312CAClBA9xeRqNhvTianYnFbL3TBF/JhdRWKm/05iVmYqh/o6MDHRiZJAzA33sMTeRFRG6m9SyVO7dei+ZlZm4Wrry8bSPCXEMMXRZHabHBNns7Gy8vb3Zs2cPo0eP1r3+5JNPsmvXLvbt23fZc9x3331s2rSJuLg4LCxavhlj2bJlvPjiixe8LkFWCNHhqou1gTbvJOTHaZcEy4+HuvKWx5taade5bQ62bhHam8vsfaT/VlySRqMhMb+SvWeK2HOmkH0pxRcs82VuoiTS14HhAU4MD3RiiJ8Dthbym4HuoKC6gLu33E1SaRL25vZ8NPUj+rv0N3RZHUKC7Fn/93//x2uvvcbOnTsZOHDgRcfJjKwQwqA0GijLPBtq47QhtyAeChKgqa7l95jbgWu4NtQ2h1u3vmDrIQFXtEit1pCQX8G+5GL2pRSxL7mYoir9GVulAvp42DE8wJEh/o4M8XPEx9FSlvsyUmV1Zdy39T6OFR7DysSK9656jxGerb+53Vj1mCDbntaCN954g5deeomtW7cybNiwNl1XemSFEEahqRFKUrUzuPkntUG34JR217KL9d9a2INrBLj10X+2cZOAK/RoNBrOFFRyMLWEA6klHEwrJq2o+oJxLjbmDPFzYIi/I5G+DgzwtpeVEYxIdUM1D+54kH05+zBTmvHGxDeY7DfZ0GW1S48JsqC92WvEiBG89957gPZmLz8/Px544IGL3uz12muv8fLLL7Np0yZGjRrV5mtKkBVCGLXGeig+czbcntLO3uaf0r6mUbf8HkvHiwRc166tXRi1/PJaDqSWcCithMPpJcRll9HQpB8TlAoIcbNhkI8Dg3wdGOTjQJiHjfTaGlB9Uz1PRj3JtvRtqBQq3rvqPcb7jDd0WVesRwXZ1atXs3jxYlauXMmIESNYvnw5P/zwA6dOncLd3Z1Fixbh7e3Nq6++CsB///tfXnjhBb799lvGjh2rO4+NjQ02NjatuqYEWSFEt9RQC0WJ+uG2IB6KU4CL/FNv5XxesG1uU4gAa+cuLV0Yp9qGJuKyyzicVsrh9BKOZpSSXVZ7wThTlYIwd1v6e9nT39uOft72RHjYYWkm4barNKobeXb3s6xPWY+liSWfT/+82/bM9qggC7BixQrdhgiRkZG8++67jBw5EoBJkyYREBDAqlWrAAgICCAtLe2CcyxdupRly5a16noSZIUQPUpDDRQmatsSmtsT8uO1bQsXC7jWbtpwq7vJrK826MoauL1efkUtxzLKOJpZytHMMo5lll5wExloO1kCna2J8LQjwtOWCE87+nja4WVvIT23naShqYH7t93P3py9OFk48b+Z/8PXztfQZbVZjwuyXU2CrBCiV6iv1i4RphdwT0Jp+sXfY+973hJhZzd4cAmTLXp7MY1GQ1ZpDSeyyonLLuNEVhnHs8oprGz5RkVbcxNC3G0Ic7Ml1N2GMHfts4edBNyOUNVQxW0bbyO+OB5fW1++nvk1zpbd6zcsEmTbSYKsEKJXq6uEgtNn2xPiz91odrE1cBUqcA7Wzto2b9Pr1hcc/GUN3F6soKKO+Jxy3eNUbgVJ+ZU0qluOHdZmKoJcbQh2tSbY1YZgNxsCnK3xd7aSm8vaqLCmkL+v/ztZlVn0d+7PZ9M/w8rUytBltZoE2XaSICuEEC2oKdEPts1r4daWtTzezEY/3HoM0H4u7Qm9Vn2jmtSiKhLyKkjIrSAhr5KE/ArSiqppukjABXCzNSfAxZoAZyv8z4ZbPyftw97SVGZyW5BSlsKtG26lrK6M8d7jefeqdzFRdo8fCCTItpMEWSGEaCXdFr0nz62Bmx+nndFtqm/5PQ7+2lDrMQDc+2ufHfxkebBerL5RTXpxNWcKKrWP/CqSCytJLayipIX+2/PZWpjg52SFr6MVPo6W+Dppn33Oft6bZ3Nj82O5c/Od1DXVcXP4zTw76llDl9QqEmTbSYKsEEK0U1Ojdr3b5u15m5/Ls1oeb26vDbSeA8FjoPbZJRxUvTeECK2y6gZSi6pILaoipbCK9KJq0ou1j/yKi2wYch4HK1O8HSy1D0fts4+jJd4O2qDrYNWzZ3S3p2/noR0PAfDGxDeYHjDdwBVdngTZdpIgK4QQnaS6WBtqc49D7tnnglOgbmHWTWWubUnwHARekeAZqW1NMDHr6qqFkaqpbyKzpJq0omoyS6rJLKkhs6SGjJJqMoqrKa+9yMYh57EyU+nCrc9fZnV9Ha16RNBdfmg5n534DBtTG36Y/YPRr2QgQbadJMgKIUQXaqzXhtncY5BzTPucexzqKy8cqzQF977gNfjsY4h25QSVadfXLYxeRW0DWaU1ZJXUkFWqDblZJTVknn3tYisrnM/W3AQ/ZysCnK3PPmv7dINdbXCxMesWIbdB3cDtG28ntiCWvs59+Xrm15ipjPcHQgmy7SRBVgghDEythpIUyImFnKOQffa5tvTCsSpzbVuC9xDwHqoNt84hsmKCuKzahiayS8+F3MySajKKzz6X1FBwmdYFe0tTgl2tCXGzIdjVhnAPW/p62eFma3zL0eVW5XLjbzdSVlfG3yP+zr9G/MvQJV2UBNl2kiArhBBGSKOB0jRtqM0+cvYRC3UtrJpgbqedsfUeCj7DwGc42Lh1dcWim6ttaCKjuJrUomrSiqpIK6omrbialMJKMktquFiCcrExI8LTjr5edvTzsmewrwM+jpYGn73dlbGLB7Y/AMDyycuZ4jfFoPVcjATZdpIgK4QQ3UTzzG32Ecg6DFmHtLO4jRduo4qDnzbQNj88Bkq/rbhitQ1NpBRWcaagkqR87eNUbgXJBZW0tJKYm605Q/0dGervyBB/R/p72WNm0vW/NXjjwBt8efJLbM1sWTNnDV42Xl1ew+VIkG0nCbJCCNGNNTVo17nNOgRZByHzkLYH96/b8arMtbO2viO0D58RYOtukJJFz1FT38TpvApOZms3gjiWWUpcdvkFG0FYmakYE+zMhDBXJoa54u9s3SX1NagbWLJhCccKjzHQZSCrZq7CVGlcPeYSZNtJgqwQQvQwteWQfRgyD0DGAe1zTfGF4xwDwHcU+J19uIRLr61ot9qGJo5llnEoreTso/iC9XEDnK2YGObKjP6ejAh0QqXsvDaErMos/vbb36ior+DhIQ9zx4A7Ou1aV0KCbDtJkBVCiB5Oo4GiM5C5HzL2acNt/kkumLW1cADfkeA/GvzGaGdwpR1BtJNareFkTjm7EgqISijgUFqJ3oytu505swZ4MTfSi0E+9p3SW/vrmV95dvezWKgs+Pnan/G1NZ4luSTItpMEWSGE6IVqy7Qztel/ah9Zh6ChWn+MiQV4D9MGW/8x2pBr1jW/EhY9V0VtA3vPFLE1Po+NJ3L11r/1c7Ji3mBvFo70w92u41ZD0Gg03LX5Lvbl7mOs11g+nPqhwW9GayZBtp0kyAohhKCpQbuebfpeSNujfa4u0h+jNNFu1BAwFvzHgd9IsLA3SLmiZ6hvVBOVUMBvx7LZcjKP6vomAEyUCq4Z4MmSsQEM9nXokNCZWpbKDb/eQL26ntcmvMbMwJntPmdHkCDbThJkhRBCXECjgcJESIvRhtrUGCjP1B+jUGp3IgsYBwHjtX22EmzFFaqub2RrfD7/+zON/SnneroH+tizZEwAswd6tXvlg4+OfsT7se/jZOHEr/N+xd7c8N+vEmTbSYKsEEKIVilJ087WpsVoH8XJ+sf1gu0EbUuCua1hahXdWlx2GV/uSeWX2GzqG9WAtu3gsavDmDPQC+UV3hxW31TP3377G8llydwQegPLxizrwKqvjATZdpIgK4QQ4oqUZ2tnalOjIXU3FJ/RP65QaW8YC5wAgeO1KySYWRmmVtEtFVXW8f2BDL6ISdVtsRvhaceT08OZFO56RS0Hh/IOsWTjEgC+nPElQ9yHdGTJbSZBtp0kyAohhOgQ5dnaQJsSpQ23Jan6x5Wm2jVsAydoH97DZFUE0SrV9Y18vjuFlbuSqajT3hw2ItCJf83ow1B/xzafb9meZfyU+BPB9sH8OOdHTFWGW1tWgmw7SZAVQgjRKUoztIE2JVobbv/aY2tqpe2rDZyoDbaeg0CpMkytolsoqarnw11nWLUnVddycOsof/41sw825iatPk9ZXRlzf5lLcW0x/xz8T+4eeHdnlXxZEmTbSYKsEEKITqfRaLfXTYmC5F3a5+pC/TEWDtr+2sCJEDQRXMLASJZIEsYlu7SGt7YksOaQ9ocjbwdLXr1+ABPCXFt9jt+Tf+fp6KexNLFkw/UbcLZ07qxyL0mCbDtJkBVCCNHlNBrtpgwpUWdbEXZDXbn+GFvPc20IgRPBwXgWsRfGISapkH/9dIzMkhoAbhrmw7Oz+mJveflWAY1Gw4I/FhBXFMfCiIU8NeKpzi63RRJk20mCrBBCCINraoScWEjeCSm7IH0fNNXpj3EKOjdbGzABrA0zgyaMS1VdI69vOs2Xe1PRaLQ7hb1+46BWzc7+mfMnd22+CxOlCb9f9zveNt5dULE+CbLtJEFWCCGE0Wmo1W6nm7JL24qQfRg0av0x7gO0oTZwAviNBgv5f1hvdiC1mH+tOUZyYRVKBTw5ow/3TAi67MoGd22+iz9z/mRu8FxeHvdyF1V7jgTZdpIgK4QQwujVlmnXsG3ur82P0z+uUIH30HOtCL4jwNTSMLUKg6ltaGLpujhWH8wAYPZAT167cSBWZhe/EexE4QkW/LEABQp+mvsToY6hXVUuIEG23STICiGE6HYq88/21+7SropQkqJ/XGUOPsO169cGjAefYWBibphaRZfSaDT8b186L/4aR6NaQx8PWz5ZNAxfp4uvYfzozkfZkraFyb6Tefeqd7uwWgmy7SZBVgghRLdXmn5uma+UKKjI1j9uYqGdpQ0Yr10ZwXuoBNsebn9KMfd9c4jCynocrEx5/5YhjA1xaXFsSlkK1627jiZNE1/P/JpIt8guq1OCbDtJkBVCCNGjaDRQdAZSo7ThNjUaqgr0x5hYaGdsA8aB/1jtjK20IvQ42aU1/ON/hziWWYZKqeCtmwZxbWTLN3Qt3bOUnxN/Zqj7UL6Y/sUV7Rp2JSTItpMEWSGEED2aRgMFp89tpZsWc2GwVZqC9xDtTWP+Y8B3JFg6GKRc0bFqG5p46qdj/BKbjVIBb/xtENcP8blgXG5VLrN+nkW9up4Pp37IOO9xXVKfBNl2kiArhBCiV9FooDBRG2zTYrQ3kVXk/GWQAtz6gt9Ibaj1HQmOAbJBQzelVmt49pfjfLc/A4UC/nv9QG4afuG6xG8ceIMvT35JH6c+rJ69GqVC2em1SZBtJwmyQgghejWNBkpStYE2fQ+k7YXiMxeOs3HX9tn6DAfvYeAVCWbWXV2tuEJqtYYXfj3B//5MB+Dl6/qzcKS/3pjS2lJm/jyTyoZKXpvwGjMDZ3Z6XW3JYa3fhFcIIYQQvYNCAU6B2sfghdrXKvK069g2P7JjoTIP4n/TPkC75Jd737PBdih4DQaXcFBJ3DBGSqWC/1zbH1OVki9iUnl27QkamzQsHhOgG+Ng4cCSfkuIzorGy8bLcMVehMzItuD/27vzsKjK/g3g98zAzLAOIjsiiBuouCEiLqlJYllGmZmV28+sfLUy3iwt03Zb1Kz0zbLUMk2z1ExNU3JJxY3FFXEBBdkR2feZ5/fHyBSBCgicGbg/13Uu4PCcM9/xuNw+PAt7ZImIiO6gvBhIiQaSjgHJJ4BrJ2oYjgDAzAJw7a4PtW69AJfugENHQHHnLVOpaQghsOD38/j6QDwA4O1RXauE2XJdOcxkZpzsZSoYZImIiOohNxm4dlwfbFNi9EdZfvV2ChXg5Au4+OmDrXNX/deW9k1dMd0khMAnu+Lwv32XIZMBK8b3QXAXZ0lqYZC9SwyyREREDUCn04+tTYn++0g7U3O4BfRjbp18AUdfwMkHcOgEtO4IWDlwUlkTEELgjS1nsO5oIiyVCvz8fH90cWv6HMQge5cYZImIiBqJTgfkXAXSTt88TgEZ5/QbONyKWqMPtA4dAfv2+rG7rbz0h2VrhtwGVK7VYdKqYzh06TrcNGpsmT4ATrbqJq2BQfYuMcgSERE1sdJ8/dq2GbH6IzMWyLoE5CYBuE1UUVrrA62mDWDrrv9Y+bmtm76XV3nrrViputyicjzy5SHEZxaiRxsNNjwXBLW5oslen0H2LjHIEhERGYnyYiA7Xr/O7fWLQHaCfmmwG1eAvBTcNuRWUtkC1k76UGvtBFg66MfjWrbWHxat9F+rbPW9vypbwEzZyG/MuF29XojQZYdwo6gcI/1c8cW4XpDLOdnLJDDIEhERmYDyEn2P7Y0r+o+5yUBeMpB7Tf8xLxWoKK7fvc0sALUtoLLRr42rtNZ/NLfUf26u1m/ra25x86MlYKbSf274qK5+rvK6ymuMeGmyo/HX8fS3R1GuFXjh3g747/DOTfK6DLJ3iUGWiIioGRBCP2ShIEO/5m1Bmv7zoutAUfbNj9eB4hv6r0vzgLKCpq1RodSHYXMr/RAIlc3NnmFbQKXRf7Sw1094s3YCrBz1h7VTk2w+sfFEEmb9fAoA8OnYHnikV/WtbBsaN0QgIiIiksn0QVBtCzh0qN012gp9oC3NA0pygbLCm0fBPz4vBCpKgPIifa9wRfHNjyVARem/PlZ+/s/z/+gl1pbpj5Lcur8/C/ubk9489R/tPIHWHQCXbvrhEg1gTB8PxGcV4ufIa/B2sG6QezYk9sjWgD2yRERE1GiE0Afa8iL9UVb5sVDfg1wZokvzgJI8oDgbKMgECjOBwgz953caMmHXVr9Gb+VavW371XudXp1O4HphGRxtVPW6vq7YI0tERERkrGQy/VhZczWAeoTLyiETOYn68cE5V/+eAJcZp/86J1F/nN9W+aL6Hda8h+iPtkH6IQ21IJfLmizE1hV7ZGvAHlkiIiIyWcU5QPoZIPWUfq3elGj9cmb/pFABnv0BvzFAl1H6sblGgpO97hKDLBERETUr+elAwn4gfp/+yEv++3tmFoDPSKDHE4D3UMlXUmCQvUsMskRERNRsCaFflzf2V+DkBv36vJWsnAD/iUDgNMCqtSTlMcjeJQZZIiIiahGEAFKigJPrgTO/6JcjA/TLgQX8HxD0AmDj3KQlMcjeJQZZIiIianG05cD57cBfi4A0/dqxMFMDvScAA17Sb/3bBOqSw+RNUhERERERGTeFOdA1FHjuAPDkRqBNgH7t22NfA5/1BCJXS1xgdQyyRERERPQ3mQzoNByYshuYsBXwGgToygH3PlJXVg3XkSUiIiKi6mQywHuw/sg4Dzj5SF1RNeyRJSIiIqLbM8IQCzDIEhEREZGJYpAlIiIiIpPEIEtEREREJolBloiIiIhMEoMsEREREZkkkwiyy5Ytg5eXF9RqNQIDA3Hs2LHbtt+4cSN8fHygVqvh5+eHHTt2NFGlRERERNRUjD7IbtiwAWFhYZg/fz6ioqLQo0cPhISEICMjo8b2hw8fxrhx4zBlyhRER0cjNDQUoaGhOHPmTBNXTkRERESNSSaEEFIXcTuBgYEICAjA0qVLAQA6nQ4eHh544YUXMHv27Grtx44di8LCQmzbts1wrl+/fujZsyeWL19eq9esyx6/RERERNRw6pLDjLpHtqysDJGRkQgODjack8vlCA4ORkRERI3XREREVGkPACEhIbdsDwClpaXIy8urchARERGRcTPqIJuVlQWtVgtnZ+cq552dnZGWllbjNWlpaXVqDwALFiyARqMxHB4eHndfPBERERE1KqMOsk1lzpw5yM3NNRxJSUlSl0REREREd2AmdQG34+DgAIVCgfT09Crn09PT4eLiUuM1Li4udWoPACqVCiqV6u4LJiIiIqImY9RBVqlUwt/fH+Hh4QgNDQWgn+wVHh6OGTNm1HhNUFAQwsPDMXPmTMO53bt3IygoqNavWzn/jWNliYiIiJpWZf6q1XoEwsitX79eqFQqsXr1anHu3Dnx7LPPCjs7O5GWliaEEGL8+PFi9uzZhvaHDh0SZmZmYuHChSI2NlbMnz9fmJubi9OnT9f6NZOSkgQAHjx48ODBgwcPHhIdSUlJd8xsRt0jC+iX08rMzMS8efOQlpaGnj17YufOnYYJXYmJiZDL/x7q279/f6xbtw5z587F66+/jo4dO2LLli3o1q1brV/Tzc0NSUlJsLGxgUwma/D39G95eXnw8PBAUlISl/syMXx2povPznTx2ZkmPjfT1dTPTgiB/Px8uLm53bGt0a8j2xJw3VrTxWdnuvjsTBefnWniczNdxvzsuGoBEREREZkkBlkiIiIiMkkMskZApVJh/vz5XALMBPHZmS4+O9PFZ2ea+NxMlzE/O46RJSIiIiKTxB5ZIiIiIjJJDLJEREREZJIYZImIiIjIJDHIEhEREZFJYpAlIiIiIpPEIEtEREREJolBloiIiIhMEoMsEREREZkkBlkiIiIiMkkMskRERERkkhhkiYiIiMgkMcgSERERkUlikCUiIiIik2QmdQHGSKfTISUlBTY2NpDJZFKXQ0RERNRiCCGQn58PNzc3yOW373NlkK1BSkoKPDw8pC6DiIiIqMVKSkpCmzZtbtuGQbYGNjY2APS/gLa2thJXQ0RERNRy5OXlwcPDw5DHbodBtgaVwwlsbW0ZZImIiIgkUJvhnZzsRUREREQmiUGWiIiIiEwSgywRERERmSSOkSUiIqJqhBCoqKiAVquVuhRqZhQKBczMzBpkiVMGWSIiIqqirKwMqampKCoqkroUaqYsLS3h6uoKpVJ5V/dhkCUiIiIDnU6HhIQEKBQKuLm5QalUcnMgajBCCJSVlSEzMxMJCQno2LHjHTc9uB0GWSIiIjIoKyuDTqeDh4cHLC0tpS6HmiELCwuYm5vj6tWrKCsrg1qtrve9ONmLiIiIqrmbXjKiO2mo31/8XUpEREREJolBloiIiKiBrF69GnZ2dlKX0SSuXLkCmUyGmJgYyWpgkCUiIqJmIykpCf/3f/9nmKjm6emJl156CdevX6/W9tKlS5g8eTLatGkDlUqFdu3aYdy4cThx4oShjUwmMxwajQYDBgzAn3/+2ZRvqYp9+/ZBJpMhJydHshoqeXh4IDU1Fd26dZOsBsmD7LJly+Dl5QW1Wo3AwEAcO3bslm3Pnj2L0aNHw8vLCzKZDEuWLKnWRqvV4s0330S7du1gYWGB9u3b491334UQohHfBdWFVidwMikHhy9lISYpBxfT85GcU4zconJUaHVSl0dERCYqPj4effr0wcWLF/Hjjz/i0qVLWL58OcLDwxEUFITs7GxD2xMnTsDf3x8XLlzAV199hXPnzmHz5s3w8fHBf//73yr3XbVqFVJTU3Ho0CE4ODjgwQcfRHx8fFO/vQZVuU7w3VAoFHBxcYGZmYRrBwgJrV+/XiiVSrFy5Upx9uxZMXXqVGFnZyfS09NrbH/s2DHxyiuviB9//FG4uLiITz/9tFqb999/X7Ru3Vps27ZNJCQkiI0bNwpra2vx2Wef1bqu3NxcAUDk5ubW963RvxSVVog/zqaJWRtjhP+7fwjP17bVeHR4fbuYuPKo2HgiSeQUlUldNhFRi1NcXCzOnTsniouLpS6lzkaMGCHatGkjioqKqpxPTU0VlpaW4vnnnxdCCKHT6UTXrl2Fv7+/0Gq11e5z48YNw+cAxObNmw1fJycnCwBi+fLlNdawatUqodFoxM6dO4WPj4+wsrISISEhIiUlRQghxP79+4WZmZlITU2tct1LL70kBg4cKIQQ4sqVK+LBBx8UdnZ2wtLSUnTp0kVs375dJCQkCABVjokTJwohhNBqteKDDz4QXl5eQq1Wi+7du4uNGzca7r93714BQOzYsUP07t1bmJubi717997xuuzsbPHkk08KBwcHoVarRYcOHcTKlSuFEMJQT3R09B3b/tvtfp/VJYdJuvzW4sWLMXXqVEyePBkAsHz5cmzfvh0rV67E7Nmzq7UPCAhAQEAAANT4fQA4fPgwHn74YYwcORIA4OXlhR9//PG2Pb3UeI4lZOPrA/E4eCkTJeV/97baqM3gqlGjsFSLorIKFJZqUabVoVwrsC8uE/viMqFUyHFPJweM7O6K+7q4wFrF1eKIiKQghEBxuTQ7fFmYK2q1jm12djZ27dqF999/HxYWFlW+5+LigqeeegobNmzA//73P8TExODs2bNYt25djbPnbzfGtfLeZWVlt2xTVFSEhQsXYs2aNZDL5Xj66afxyiuvYO3atbjnnnvg7e2NNWvWYNasWQCA8vJyrF27Fh9//DEAYPr06SgrK8OBAwdgZWWFc+fOwdraGh4eHvjll18wevRoxMXFwdbW1lDPggUL8MMPP2D58uXo2LEjDhw4gKeffhqOjo4YPHiwobbZs2dj4cKF8Pb2RqtWre543Ztvvolz587h999/h4ODAy5duoTi4uIa33dd2jYUyZJBWVkZIiMjMWfOHMM5uVyO4OBgRERE1Pu+/fv3x9dff40LFy6gU6dOOHnyJA4ePIjFixc3RNlUSxVaHT7/8xK++PMiKkd1uNtZ4L4uzrivizP6trOHuaLqXx5lFTokZhdi+6k0bD+dggvpBdgTm4E9sRmwszyHl4M74cnAttWuIyKixlVcrkWXebskee1z74TAUnnnuHLx4kUIIeDr61vj9319fXHjxg1kZmbi4sWLAAAfH5861VJUVIS5c+dCoVBUCYf/Vl5ejuXLl6N9+/YAgBkzZuCdd94xfH/KlClYtWqVIcj+9ttvKCkpweOPPw4ASExMxOjRo+Hn5wcA8Pb2Nlxrb28PAHBycjIE7tLSUnzwwQfYs2cPgoKCDNccPHgQX331VZVa33nnHdx33321vi4xMRG9evVCnz59AOg7CG+lLm0bimRBNisrC1qtFs7OzlXOOzs74/z58/W+7+zZs5GXlwcfHx8oFApotVq8//77eOqpp255TWlpKUpLSw1f5+Xl1fv1CUjNLcZL62NwLEE/FunR3u6YMrAdurja3vZ/1UozOTo42eClYBu8FNwRF9Lzse1UKn6NScbV60WYv/Us1hy5irkjfTGks1NTvR0iIjIhohZzYmrT5p/GjRsHhUKB4uJiODo64ttvv0X37t1v2d7S0tIQYgHA1dUVGRkZhq8nTZqEuXPn4siRI+jXrx9Wr16Nxx9/HFZWVgCAF198EdOmTcMff/yB4OBgjB49+ravd+nSJRQVFRkCaqWysjL06tWryrnKkFnb66ZNm4bRo0cjKioKw4cPR2hoKPr3719jHXVp21Ca3c9qf/rpJ6xduxbr1q1D165dERMTg5kzZ8LNzQ0TJ06s8ZoFCxbg7bffbuJKm6c959Lxys8nkVNUDiulAu8/4ofQXu71ulcnZxuE3WeDF+/tgPXHk7B49wVcyijApFXHMaSzI+aO9EUHJ5sGfgdERPRvFuYKnHsnRLLXro0OHTpAJpMhNjYWjzzySLXvx8bGolWrVnB0dESnTp0AAOfPn68W9Gry6aefIjg4GBqNBo6Ojndsb25uXuVrmUxWJTw7OTnhoYcewqpVq9CuXTv8/vvv2Ldvn+H7zzzzDEJCQrB9+3b88ccfWLBgARYtWoQXXnihxtcrKCgAAGzfvh3u7lX/zVWpVFW+rgzLtb3u/vvvx9WrV7Fjxw7s3r0bw4YNw/Tp07Fw4cJqddSlbYO54yjaRlJaWioUCkWVAdRCCDFhwgQxatSoO17v6elZ42SvNm3aiKVLl1Y59+6774rOnTvf8l4lJSUiNzfXcCQlJXGyVx1VaHXi7a1nDZO2Rn5+QCRkFjToa+QUlYn3tp0VHV7fLjxf2ya852wXn+6OExVaXYO+DhFRS2bKk72GDx8u3N3dazXZq0uXLvWa7HUnlZO9/mnz5s3i35Frx44dQqPRiHfeeee2GUUIIWbPni38/PyEEEIcOnRIABBZWVmG7+fl5QmVSiW+//77W96jcrLXP99bba77t+XLlwsbGxshRPXJXrdr+28NNdlLssGGSqUS/v7+CA8PN5zT6XSGJTLqq6ioqNrAbYVCAZ3u1ss6qVQq2NraVjmobj7aeR4rDyUAAKYMbIdfpvWHl4PVHa6qG42FOd4Y2QV/vDwYwb7O0OoEluy5iAkrjyIzv/TONyAiomZt6dKlKC0tRUhICA4cOICkpCTs3LkT9913H9zd3fH+++8D0PeQrlq1ChcuXMCgQYOwY8cOxMfH49SpU3j//ffx8MMPN3qtISEhsLW1xXvvvWeY9F5p5syZ2LVrFxISEhAVFYW9e/caxv56enpCJpNh27ZtyMzMREFBAWxsbPDKK6/g5ZdfxnfffYfLly8jKioKX3zxBb777rtb1lCb6+bNm4dff/0Vly5dwtmzZ7Ft27ZbjkOuS9sGU+sI3gjWr18vVCqVWL16tTh37px49tlnhZ2dnUhLSxNCCDF+/Hgxe/ZsQ/vS0lIRHR0toqOjhaurq3jllVdEdHS0uHjxoqHNxIkThbu7u2H5rU2bNgkHBwfx6quv1rouLr9VN1uirxl6YjdFJTXZ6/58Ikn4zP1deL62TfR5b7c4fCnrzhcREdFtmXKPrBD6pasmTpwonJ2dhbm5ufDw8BAvvPBClR7MSnFxcWLChAnCzc1NKJVK4enpKcaNGyeioqIMbdBIPbJCCPHmm28KhUJhWJqr0owZM0T79u2FSqUSjo6OYvz48VXqf+edd4SLi4uQyWSG5bd0Op1YsmSJ6Ny5szA3NxeOjo4iJCRE7N+/XwhRc49sba579913ha+vr7CwsBD29vbi4YcfFvHx8UKI6j2yt2v7bw3VIysTQtqdApYuXYpPPvkEaWlp6NmzJz7//HMEBgYCAIYMGQIvLy+sXr0agH4rtHbt2lW7x+DBgw1jS/Lz8/Hmm29i8+bNyMjIgJubG8aNG4d58+ZBqVTWqqa8vDxoNBrk5uayd/YOziTn4rHlh1FSrsO0Ie3x2oi6zQC9WxfT8/GftVG4mFEAuQx4ObgT/jO0AxTyOy/VQkRE1ZWUlCAhIQHt2rWDWq2WupxmbcqUKcjMzMTWrVulLqXJ3e73WV1ymORB1hgxyNZOdmEZHvriIJJzijG4kyNWTgqQJEAWlVVg3q9n8XPkNQDAPZ0csfTJXrBVm9/hSiIi+jcG2caXm5uL06dP47777sPWrVurrRrQEjRUkOWCnFQvFVodpq+NQnJOMbxaW+LzJ3pJ1gtqqTTDwjE98Mlj3aE2l+PAhUw8vjwC6XklktRDRER0Ow8//DCGDx+O559/vkWG2IbU7JbfoqbxwY7ziIi/DiulAl9P6AONpfS9n2P6eMDX1RaTVh3H+bR8PPq/w1g9OQAdnblEFxERGY9/LrVFd4c9slRnm6OvGVYoWPR4D3QyoqDYzV2Dzf/pD28HKyTnFGP0l4dx/Eq21GURERFRI2CQpTrJKSrD/F/PAgBevLcDRnRzlbii6jzsLfHztP7o1dYOeSUVeOqbo9h5JlXqsoiIiKiBMchSnfxv32XklVSgs7MNXgruJHU5t2RvpcS6Z/oh2NcZZRU6TFsbhbVHr0pdFhGRyeBccGpMDfX7i0GWai05pxirD18BAMy+38fol7iyUCqw/OneeCqwLYQA3th8Bt9HXJG6LCIio1a5vWpRUZHElVBzVvn769/b+dYVJ3tRrS36Iw5lFTr087bHkM533mvaGJgp5HgvtBusVGb4+kA85v16FjqdwKQB1dcjJiIi/W6YdnZ2yMjIAABYWlpCJjPujgsyHUIIFBUVISMjA3Z2dlAoFHd1PwZZqpXY1Dxsjk4GAMy+39ek/lKTyWSYc78P5DIZlu+/jLd+Owet0G+lS0RE1bm4uACAIcwSNTQ7OzvD77O7wSBLtfLRzvMQAhjp54qeHnZSl1NnMpkMr43oDIUcWLb3Mt7ddg5CCDwzyFvq0oiIjI5MJoOrqyucnJxQXl4udTnUzJibm991T2wlBlm6o8OXs7AvLhNmchlmhXSWupx6k8lkeGV4ZyhkMnz+5yW8tz0WWp3Ac4PbS10aEZFRUigUDRY4iBoDJ3vRbel0Ah/+fh4A8GRgW3g5WElc0d2RyWQIG94ZLw3rCABY8Pt5rLq5Ji4RERGZFgZZuq3tp1Nx6lourJQKvHgz/DUHL9/XyfB+3v7tHH46niRxRURERFRXDLJ0S2UVOnyyKw4A8Ow97eFgrZK4oob1cnBHPHNzwtfsTaew7VSKxBURERFRXTDI0i1tiUlGYnYRHKxVeGZQ85vhL5PJ8MZIX4zr6wGdAGauj0F4bLrUZREREVEtMcjSLa0/lggA+L+BXrBSNc95gTKZDO+F+uHhnm6o0AlMWxuFw5eypC6LiIiIaoFBlmp0IT0fUYk5UMhleMy/jdTlNCqFXIaFY3oYtrN95vsTiEq8IXVZREREdAcMslSjH2/2xg7zcYKTjVriahqfuUKOpU/2woAOrVFUpsXkVcdxIT1f6rKIiIjoNhhkqZqScq1hF69xfdtKXE3TUZsrsGJCH/T0sENucTkmfHsM125wr3EiIiJjxSBL1ew6m4aconK4atS4p5Oj1OU0KUulGVZNCkAHJ2uk5ZVgwrfHcL2gVOqyiIiIqAYMslTN+mP6NVXH9PGAQi6TuJqm18pKiTVT+sJNo0Z8ViEmrz6OgtIKqcsiIiKif2GQpSquZBUiIv46ZDLg8T7Ne5LX7bhqLPD9lEC0sjTHqWu5eG7NCZRWaKUui4iIiP6BQZaq2HBC3xt7T0dHtGllKXE10urgZI3Vk/vCUqnAoUvXEbbhJLQ6IXVZREREdBODLBmUa3XYeOIaAOCJAA+JqzEOPTzs8PX4PjBXyLD9dCre/u0shGCYJSIiMgYMsmTw5/kMZBWUwsFaiWG+zlKXYzQGdnTAp2N7QiYDvo+4imV7L0ldEhEREYFBlv6hciev0f5toDTjb41/erC7G+Y/2AUAsPCPC4ZfKyIiIpIO0woBAFJyirH/QiYAYGwfDiuoyaQB7TB9aHsAwOubT2P3uXSJKyIiImrZGGQJALDxxDXoBBDYzh7ejtZSl2O0XhneGY/3aQOdAGasi8KJK9lSl0RERNRiMcgShBD4OUq/WkFL2smrPmQyGT54xA/DfJxQWqHD/63mVrZERERSYZAlxKXnIym7GCozOUK6ukhdjtEzU8ix9Mne6N3WDnklFZjw7TEk5xRLXRYREVGLwyBLCI/NAAAM6OAAC6VC4mpMg4VSgZVVtrI9ihuFZVKXRURE1KIwyBLCY/WTlu71cZK4EtNiZ6nE9//XF64aNS5n6reyLSrjVrZERERNRfIgu2zZMnh5eUGtViMwMBDHjh27ZduzZ89i9OjR8PLygkwmw5IlS2psl5ycjKeffhqtW7eGhYUF/Pz8cOLEiUZ6B6btekEpopNyAADDfBlk68rNzgLf/19f2FmaIyYpB/9ZG4VyrU7qsoiIiFoESYPshg0bEBYWhvnz5yMqKgo9evRASEgIMjIyamxfVFQEb29vfPjhh3BxqXks540bNzBgwACYm5vj999/x7lz57Bo0SK0atWqMd+KydoXlwkhgC6utnDVWEhdjknq6GyDbycGQG0ux764TLz68ynouJUtERFRo5M0yC5evBhTp07F5MmT0aVLFyxfvhyWlpZYuXJlje0DAgLwySef4IknnoBKpaqxzUcffQQPDw+sWrUKffv2Rbt27TB8+HC0b9++Md+KyQo/rx9WwN7Yu+Pv2QpfPuUPhVyGzdHJWPB7rNQlERERNXuSBdmysjJERkYiODj472LkcgQHByMiIqLe9926dSv69OmDMWPGwMnJCb169cKKFStue01paSny8vKqHC1BWYUOBy5kAQC3pG0AQ32c8PHo7gCAFX8l4Mt9lyWuiIiIqHmTLMhmZWVBq9XC2blqgHJ2dkZaWlq97xsfH48vv/wSHTt2xK5duzBt2jS8+OKL+O677255zYIFC6DRaAyHh0fL2Nnq+JVsFJRWwMFahe7uGqnLaRZG+7fBGw/4AgA+2nkeP3IrWyIiokYj+WSvhqbT6dC7d2988MEH6NWrF5599llMnToVy5cvv+U1c+bMQW5uruFISkpqwoqls8ewWoEj5HKZxNU0H1Pv8ca0IX9vZbv9VKrEFRERETVPkgVZBwcHKBQKpKdX3a8+PT39lhO5asPV1RVdunSpcs7X1xeJibfuGVOpVLC1ta1yNHdCCMP6sff6cFhBQ3s1pDPG9W0LIYCZG6Jx4EKm1CURERE1O5IFWaVSCX9/f4SHhxvO6XQ6hIeHIygoqN73HTBgAOLi4qqcu3DhAjw9Pet9z+bocmYhErOLoFTIMaijg9TlNDsymQzvhXbDyO6uKNcKPLcmEpFXb0hdFhERUbMi6dCCsLAwrFixAt999x1iY2Mxbdo0FBYWYvLkyQCACRMmYM6cOYb2ZWVliImJQUxMDMrKypCcnIyYmBhcunTJ0Obll1/GkSNH8MEHH+DSpUtYt24dvv76a0yfPr3J358xq9wEoV/71rBSmUlcTfOkkMvw6eM9MaijA4rLtfi/1ccRl5YvdVlERETNhqRBduzYsVi4cCHmzZuHnj17IiYmBjt37jRMAEtMTERq6t/jC1NSUtCrVy/06tULqampWLhwIXr16oVnnnnG0CYgIACbN2/Gjz/+iG7duuHdd9/FkiVL8NRTTzX5+zNm4ef1wwqGcTevRqU0k+Or8f7o3dYOucXlePrbo0jIKpS6LCIiomZBJoTgyu3/kpeXB41Gg9zc3GY5XjanqAz+7+2BVifw16tD4WFvKXVJzV5uUTnGfh2B82n5cNOo8dPzQWjTir/uRERE/1aXHNbsVi2gO9t/IRNanUBnZxuG2CaisTTHD88EwtvRCim5JXjqm6NIzyuRuiwiIiKTxiDbAhlWK+BuXk3KwVqFdc/0g4e9Ba5eL8JT3xzF9YJSqcsiIiIyWQyyLUyFVod9cfogG8wg2+RcNGqse6YfXDVqXMoowPhvjyG3qFzqsoiIiEwSg2wLc+LqDeSVVKCVpTl6erSSupwWycPeEj88EwgHayXOpeZh4qpjKCitkLosIiIik8Mg28IcvJgFABjcyREK7uYlmfaO1vjhmUDYWZojJikHE1cyzBIREdUVg2wLc/xKNgCgn3driSshHxdbrPm/QNiqzRB59QbDLBERUR0xyLYgZRU6xCTlAAD6eNlLWwwBAPzaaPDDMwyzRERE9cEg24KcTclFaYUOrSzN0d7RSupy6KbubewYZomIiOqBQbYFOXHlBgDA39MeMhnHxxoThlkiIqK6Y5BtQSrHxwZ4cbUCY/TvMDvh26PILebSXERERLfCINtCCCEQeVXfI8vxscarexs7rH2mH2zVZohKzMGTK45w0wQiIqJbYJBtIRKyCnG9sAxKMzm6ud9+32KSll8bDdY/G4TWVkqcTcnD2K+PcDtbIiKiGjDIthCV42N7trGDykwhcTV0J13cbPHT80FwsdXvADZmeQSSsoukLouIiMioMMi2EJXjY/twfKzJaO9ojY3PB6GtvSUSs4swZnkELmUUSF0WERGR0WCQbSH+Hh/LIGtKPOwtsfH5IHR0skZaXgnGfhWBM8m5UpdFRERkFBhkW4CsglLEZxUCAPzbcqKXqXG2VWPDc0Ho5m6L64VlGPtVBP66mCl1WURERJJjkG0BKsfHdna2gcbSXOJqqD7srZRYN7Ufgrxbo7BMi8mrjmNLdLLUZREREUmKQbYFOMHxsc2Crdocq/8vAA/1cEOFTmDmhhgs338ZQgipSyMiIpIEg2wLcILjY5sNlZkCn43tiWcGtgMAfPj7ebz92zlodQyzRETU8jDINnPFZVrD5KA+nhwf2xzI5TLMfbAL5o70BQCsPnwFM9ZFobhMK3FlRERETYtBtpmLScpBhU7AxVaNNq0spC6HGtAzg7zx+bheUCrk+P1MGsZ+HYG0XG6cQERELQeDbDP3z/GxMplM4mqooY3q4YY1U/qilaU5Tl3LxcPLDuLUtRypyyIiImoSDLLNnGF8rCfHxzZXgd6t8ev0gejoZI30vFI8/lUEtp1KkbosIiKiRscg24xpdQJRholeHB/bnLVtbYlN/+mPIZ0dUVKuw4x10Viy5wJXNCAiomaNQbYZi0vLR35pBaxVZvBxsZG6HGpkNmpzfDsxAFNurmiwZM9FPP9DJPJKyiWujIiIqHEwyDZjJ67qx8f2amsHMwUfdUugkMvw5oNd8NFoP5grZNh1Nh0PLz2EuLR8qUsjIiJqcEw3zVjljl5cdqvlGRvQFhuf7w83jRoJWYUIXXaIO4EREVGzwyDbjFWuWBDAjRBapJ4edtj24iAM6uiA4nItZm6IwZtbzqC0guvNEhFR88Ag20xl5pciJbcEMhnQw8NO6nJIIvZWSqye3BcvDusIAFhz5Coe/+oIrl4vlLgyIiKiu8cg20zFpuYBANq1toKVykziakhKCrkMYfd1wqpJAdBYmONkUg4e+Owv/BJ5jasaEBGRSWOQbabO3Qyyvm62EldCxmKojxO2vzgQfb3sUVimxX83nsSL62OQW8xVDYiIyDQZRZBdtmwZvLy8oFarERgYiGPHjt2y7dmzZzF69Gh4eXlBJpNhyZIlt733hx9+CJlMhpkzZzZs0UbuXIo+yHZxZZClv7VpZYkfn+2H/97XCQq5DL+dTMEDn/2FYwnZUpdGRERUZ5IH2Q0bNiAsLAzz589HVFQUevTogZCQEGRkZNTYvqioCN7e3vjwww/h4uJy23sfP34cX331Fbp3794YpRu1yh7ZLuyRpX9RyGV4YVhHbHw+CG3tLZGcU4wnvo7AxzvPo6ScE8GIiMh0SB5kFy9ejKlTp2Ly5Mno0qULli9fDktLS6xcubLG9gEBAfjkk0/wxBNPQKVS3fK+BQUFeOqpp7BixQq0atWyZu0Xl2kRn1kAAOjKHlm6hd5tW2H7iwMxuncb6ATwv32X8eAXBxGVeEPq0oiIiGpF0iBbVlaGyMhIBAcHG87J5XIEBwcjIiLiru49ffp0jBw5ssq9b6W0tBR5eXlVDlMWl54PnQAcrJVwtLl12CeyUZtj0eM9sPxpfzhYq3ApowCPfXkY728/h+Iy9s4SEZFxkzTIZmVlQavVwtnZucp5Z2dnpKWl1fu+69evR1RUFBYsWFCr9gsWLIBGozEcHh4e9X5tY1C5YoGvqy1kMpnE1ZApGNHNBXvC7sGjvdyhE8CKvxJw/2cHcDT+utSlERER3ZLkQwsaWlJSEl566SWsXbsWarW6VtfMmTMHubm5hiMpKamRq2xcholeHB9LdWBnqcTisT2xclIfuNiqceV6EcZ+fQSzNp7E9YJSqcsjIiKqRtIg6+DgAIVCgfT09Crn09PT7ziR61YiIyORkZGB3r17w8zMDGZmZti/fz8+//xzmJmZQaut/uNSlUoFW1vbKocpM0z04vhYqod7fZzxR9g9GNdX/5OJjZHXMHThPqw5chVaHdedJSIi4yFpkFUqlfD390d4eLjhnE6nQ3h4OIKCgup1z2HDhuH06dOIiYkxHH369MFTTz2FmJgYKBSKhirfKOl0wjC0gEGW6stWbY4Fj3bHL9P6o4urLfJKKvDmljN45H+HcDIpR+ryiIiIAACSb/kUFhaGiRMnok+fPujbty+WLFmCwsJCTJ48GQAwYcIEuLu7G8a7lpWV4dy5c4bPk5OTERMTA2tra3To0AE2Njbo1q1bldewsrJC69atq51vjq5mF6GoTAuVmRztHKykLodMnL9nK/z2wkD8cOQqFv4Rh1PXchH6v0N43N8DYcM7wdm2dsN3iIiIGoPkQXbs2LHIzMzEvHnzkJaWhp49e2Lnzp2GCWCJiYmQy//uOE5JSUGvXr0MXy9cuBALFy7E4MGDsW/fvqYu3+hUjo/1cbGBmaLZDYEmCSjkMkzs74UH/Fyx4PdYbIpKxoYTSdh6MgXP3uONZ+/x5jbIREQkCZngZuvV5OXlQaPRIDc31+TGy36y6zyW7b2McX09sODRlrcRBDW+yKs38MGOWERe1a8362ijQth9nTDGvw3/80RERHetLjmM/+o0M9yalhqbv2cr/Px8EL58qjc8W1siM78Uczadxv2f/YXfT6dCxwlhRETURBhkm5nY1HwAXHqLGpdMJsP9fq7Y/fJgzH+oC+wszXExowDT1kZh5BcH8cfZNPCHPURE1NgYZJuR6wWlSMsrgUwGdHZhkKXGpzSTY/KAdtg/ayheHNYR1iozxKbm4dk1kRi19BD+PJ/OQEtERI2GQbYZqeyN9WptBWtOvqEmpLEwR9h9nXDwtaGYPrQ9LJUKnE7Oxf+tPoFRSw9hx+lUrkFLREQNjkG2GTmXmgsA8HW1kbgSaqnsLJWYFeKDv14diufu8YaFuT7Q/mdtFIIX78ePxxJRWlF9UxIiIqL6YJBtRjjRi4xFa2sV5jzgi4OvDcWL93aAxsIcCVmFmLPpNAZ+tBdf7ruM3KJyqcskIiITxyDbjBi2puVELzISra1VCBveGYdn34u5I33hqlEjM78UH+08j34LwvHG5tO4lJEvdZlERGSiGGSbiZJyLS5nFgIAurhqJK6GqCorlRmeGeSN/bOG4pPHusPHxQbF5VqsPZqI4MUHMP7bowiPTefSXUREVCecEdRMXEjPh1YnYG+lhLOtSupyiGqkNJNjTB8PPObfBkfis7H6cAJ2n0vHXxez8NfFLLS1t8QTfT0wxt8Djjb8fUxERLfHINtM/HN8rEwmk7gaotuTyWQIat8aQe1bIym7CGuOXMX6Y4lIzC7CxzvjsPiPCxje1RlP9vVE//atIZfz9zQREVXHINtMxHJ8LJkoD3tLvP6AL14O7oRtp1Kw7lgiohNzsON0GnacTkNbe0uM8W+DR/3bwN3OQupyiYjIiDDINhOGiV5csYBMlIVSgTF9PDCmjwdiU/Ow7mgitkQnIzG7CIt2X8DiPRcwoL0DxvRpg+FdXGChVEhdMhERSYxBthnQ6YRhMwRfBllqBnxdbfFuaDfMecAH20+l4peoazgSn42Dl7Jw8FIWbFRmGNndFaG93NHXy55DD4iIWigG2WYg6UYRCkoroDSTw9vRSupyiBqMpdLM0EubeL0Iv0Rdw8+R15CcU4z1x5Ow/ngS3DRqjOrpjkd6uaOzCzcDISJqSWSCG6FXk5eXB41Gg9zcXNjaGn8P5++nUzFtbRT83DX47YWBUpdD1Kh0OoEjCdexJToZv59OQ35pheF7Pi42eLinOx7s7goPe0sJqyQiovqqSw5jj2wzUDnRi1vTUksgl8vQv70D+rd3wDsPd8Of5zOwOToZ++IycD4tH+d3nsdHO8+jd1s7PNTDDSP9XOFkq5a6bCIiagQMss3ApcwCAEAnZwZZalnU5go84OeKB/xckVNUhh2n0/DbyRQcSbiOqMQcRCXm4J1t5xDYzh4PdnfDiG4ucLDm+rRERM0Fg2wzEH9zRy+Oj6WWzM5SiScD2+LJwLbIyCvB9tOp+O1kCqISc3AkPhtH4rMx79cz6OfdGiO7u2JEVxe0ZqglIjJpHCNbA1MaI6vTCfjO24nSCh32vTIEXg4Ms0T/lJRdhN/PpGL7qVScvJZrOC+XAUHtW+MBP1eEdGVPLRGRsahLDmOQrYEpBdmk7CIM+ngvzBUyxL4zAmYKudQlERmtpOwibD+tD7Wnk6uG2n7ef4dabo9LRCQdBtm7ZEpBdv+FTExceQwdnKyxJ2yw1OUQmYyr1wtv7h5WPdT2bWePkX6uCOnmAicbThQjImpKXLWgBYm/OdHLm0MKiOrEs7UVpg1pj2lD2iMpuwg7Tqdix2n98APDmNqtZ9HXy14/ppahlojI6DDImrjKiV7tnawlroTIdHnYW+K5we3x3OD2f4+pPZ2Gk0k5OJqQjaMJ2Zi/9SwC29ljZHc33M/VD4iIjAKDrImLz2KPLFFD8rC3xLP3tMez97THtRtF+P10GradTsXJpL9XP5j/6xkEtW+NkX76Jb3srZRSl01E1CJxjGwNTGmMbNCCcKTmluCXaf3h79lK6nKImq1brX5gJpdhYEcHPNTdDfd1dYat2lzCKomITB8ne90lUwmyRWUV6DJvFwAgZt59sLNkrxBRU0jKLsK2U6nYdioFZ1PyDOeVZnIM7eyIh3q4IdjXGWpzhYRVEhGZJk72aiEqx8faWykZYomakIe9pWGi2OXMAmw7mYqtJ5NxObMQu86mY9fZdFirzBDS1QWhvdzQv70DFHKZ1GUTETU7DLImLD7r5o5eHB9LJJn2jtZ4KbgjXhzWAefT8rH1ZAq2xqQgOacYv0Rdwy9R1+Boo8JD3d3waG93dHWzhUzGUEtE1BAYZE2YYektbk1LJDmZTAZfV1v4utpi1vDOiEy8gS3Rydh+OhWZ+aVYeSgBKw8loLOzDR7t7Y7QXu5wtuVyXkREd4NB1oRVDi3wduTSW0TGRC6XIcDLHgFe9pj/UFf8dTETm6KTsftcOuLS87Hg9/P4aOd5DOjggMf82yCkqwvH0xIR1YNR7Ge6bNkyeHl5Qa1WIzAwEMeOHbtl27Nnz2L06NHw8vKCTCbDkiVLqrVZsGABAgICYGNjAycnJ4SGhiIuLq4R34E0uPQWkfFTmskxzNcZy57sjeNvBGPBo34I8GoFnQD+upiFl9bHIOD9PXhj82mcTMoB598SEdVerXpk7e3t63RTmUyGqKgoeHp63rHthg0bEBYWhuXLlyMwMBBLlixBSEgI4uLi4OTkVK19UVERvL29MWbMGLz88ss13nP//v2YPn06AgICUFFRgddffx3Dhw/HuXPnYGXVPEKfEAIJ7JElMikaC3OM69sW4/q2xdXrhdgUlYyfI68hOacYa48mYu3RRHRytsbjfTzwaO82XJ+WiOgOarX8llwux5IlS6DRaO54QyEE/vOf/+DMmTPw9va+Y/vAwEAEBARg6dKlAACdTgcPDw+88MILmD179m2v9fLywsyZMzFz5szbtsvMzISTkxP279+Pe+655441mcLyW2m5Jei3IBwKuQyx74yA0swoOteJqI50OoGI+OvYeCIJv59JQ2mFDgCgVMgxvKsznuzbFv28W0POVQ+IqIVolOW3nnjiiRp7SGvywgsv1KpdWVkZIiMjMWfOHMM5uVyO4OBgRERE1La0O8rN1S9eXteeZWNWOdGrrb0lQyyRCZPLZRjQwQEDOjjg7eJybDuVgvXHknA6OffmWrWp8GxtiScC2uIx/zZwtOHWuERElWoVZHU6XZ1ump+fX6t2WVlZ0Gq1cHZ2rnLe2dkZ58+fr9Nr3opOp8PMmTMxYMAAdOvWrcY2paWlKC0tNXydl5dXYztjcplLbxE1OxoLczwV6ImnAj1xJjkX648nYkt0Cq5eL8JHO89j8e44jOjmivH9PBHg1YrLeBFRi1frrrxt27bVOdAag+nTp+PMmTNYv379LdssWLAAGo3GcHh4eDRhhfXDpbeImrdu7hq8F+qHY28Mw8ePdUdPDzuUawV+O5mCx7+KQMiSA1gTcQX5JeVSl0pEJJlaB9nQ0FB4eHjgjTfewKVLlxrkxR0cHKBQKJCenl7lfHp6OlxcXO76/jNmzMC2bduwd+9etGnT5pbt5syZg9zcXMORlJR016/d2Lj0FlHLYKk0w+N9PLBl+gBse2EgxvX1gIW5AhfSC/Dmr2fR74NwvLnlDC5lFEhdKhFRk6t1kE1ISMBzzz2H9evXo3Pnzhg8eDDWrFmD4uLier+4UqmEv78/wsPDDed0Oh3Cw8MRFBRU7/sKITBjxgxs3rwZf/75J9q1a3fb9iqVCra2tlUOY8elt4hanm7uGix4tDuOvD4Mbz3UBe0drVBYpsWaI1cRvHg/xn97FH+eT4dOxyW8iKhlqHWQ9fDwwLx583D58mXs2bMHXl5emDZtGlxdXfH888/j+PHj9SogLCwMK1aswHfffYfY2FhMmzYNhYWFmDx5MgBgwoQJVSaDlZWVISYmBjExMSgrK0NycjJiYmKq9BJPnz4dP/zwA9atWwcbGxukpaUhLS3trkK3MSkp1+LaDf17YY8sUcujsTDHpAHtsCdsMNY+E4j7ujhDJtOvS/t/q09g6KJ9WHkwgcMOiKjZq9XyW7eSn5+P9evXY/Xq1Thy5Ai6deuGkydP1vk+S5cuxSeffIK0tDT07NkTn3/+OQIDAwEAQ4YMgZeXF1avXg0AuHLlSo09rIMHD8a+ffv0b+oWEyBWrVqFSZMm3bEeY19+Ky4tHyFLDsBGbYZT84dzwgcRIfF6EdYcuYL1x5OQX1IBALBRmWFsgAcmDfBCm1aWEldIRFQ7dclhdxVkASA+Ph4rV67El19+iby8PJSXm34PgLEH2d9Pp2La2ij08LDDr9MHSF0OERmRorIKbIpKxqpDCbh8cyy9XAbc380V/zewHfw9W0lcIRHR7dUlh9VrAdLi4mJ8//33GDJkCDp27Ij169cjLCwMV65cqc/tqI7iby691Z7jY4noXyyVZni6nyd2vzwYqyYFYGAHB+gEsP10KkZ/eRiP/u8Qdp5J4zhaImoWar0hAgAcOXIEK1euxE8//YSysjI8+uij2LNnD4YOHdpY9VENLnPpLSK6A7lchqE+Thjq44TY1DysPJiAX2NSEJWYg+d/iIS3gxWeGeSNR3u7Q22ukLpcIqJ6qfXQgi5duiAuLg69evXClClT8OSTT9Zqy1pTZOxDC0KXHUJMUg7+91RvPODnKnU5RGQiMvJKsPrwFfxw5Crybo6jdbBWYmKQFyYEeUFjaS5xhUREjbRFbXBwMH788Uf06NHjrguk+hNCcDMEIqoXJ1s1Xh3hg/8M7YANx5Ow8mACknOKsWj3BSzffxnj+rbFlEHt4KqxkLpUIqJauevJXs2RMffIZhWUos97eyCTAbHvjOCPBImo3sq1Ouw4nYrl++MRm6rfmttcIcMjvdzx3OD2aM/l/YhIAg0+2at37964ceNGrQsYOHAgkpOTa92eaq9yRy93OwuGWCK6K+YKOR7u6Y4dLw7EqskBCGxnj3KtwE8nriF48X5M+yESZ5JzpS6TiOiWajW0ICYmBidPnoS9vX2tbhoTE4PS0tK7Koxq9vewAvaUEFHDkMlkGNrZCUM7OyHy6g0s338Zu8+l4/czafj9TBoGd3LE9KEd0Ldd7f4NICJqKrUeIzts2DDUdhQCF+hvPJVLb3FrWiJqDP6erbBiQh9cSM/Hl/suY+vJFOy/kIn9FzIR4NUK04d2wOBOjvx7noiMQq2CbEJCQp1v3KZNmzpfQ3dW2SPbnhO9iKgRdXK2wadje+Ll4E5YfuAyfj5xDcev3MCkVcfh567BjHs74D5fZ8jlDLREJJ1aBVlPT8/GroNqqXKMLIcWEFFTaNvaEh884ocX7+2IFX/FY93RRJxOzsVzayLR2dkG0+/tgJF+rlAw0BKRBOq1sxdJo1yrQ2J2EQAuvUVETctFo8abD3bBwdeGYvrQ9rBRmSEuPR8v/hiN+xbvx8YTSSjX6qQuk4haGAZZE5KSU4wKnYDaXA4XW7XU5RBRC9TaWoVZIT44OPtehN3XCXaW5ojPKsSsn09h6MJ9WHc0EaUVWqnLJKIWgkHWhCRlFwMA2rSy5EQLIpKUxsIcLw7riIOv3Ys59/vAwVqJazeK8frm0xjyyT58d/gKSsoZaImocTHImpBrN/TDCtq04q47RGQcrFVmeG5we/z16r2Y92AXONuqkJpbgvlbz2LQx3vxzV/xKCqrkLpMImqm6hVkc3Jy8M0332DOnDnIzs4GAERFRXEThEZ27Ya+R9ajlaXElRARVWWhVOD/BrbD/llD8W5oN7hp1MjML8V722Mx6KO9+N++SygoZaAlooZV63VkK506dQrBwcHQaDS4cuUKpk6dCnt7e2zatAmJiYn4/vvvG6NOApDEHlkiMnJqcwXG9/PE2D4e2Bx9Dcv2XkZidhE+3hmHr/bH4/8GtMOkAV7QWJhLXSoRNQN17pENCwvDpEmTcPHiRajVf084euCBB3DgwIEGLY6qquyRbcMeWSIyckozOcYGtMWf/x2MRWN6wNvBCrnF5fh0zwUM/PBPLNwVh+zCMqnLJCITV+cge/z4cTz33HPVzru7uyMtLa1BiqKacYwsEZkaM4Uco/3bYHfYYHw+rhc6OVsjv7QCS/dewoAP/8T7288hI69E6jKJyETVOciqVCrk5eVVO3/hwgU4Ojo2SFFUXWmFFul5pQAAD3v2yBKRaVHIZRjVww07X7oHy5/2Rzd3WxSXa7HirwQM/Hgv5v16Bsk5xVKXSUQmps5BdtSoUXjnnXdQXl4OAJDJZEhMTMRrr72G0aNHN3iBpJd8c1iBpVKBVpYcW0ZEpkkul2FENxf8NmMgVk0OQO+2diir0OH7iKsY/PFezNp4EpdvbsVNRHQndQ6yixYtQkFBAZycnFBcXIzBgwejQ4cOsLGxwfvvv98YNRL+OT7WgmvIEpHJk8lkGNrZCb9M6491zwSif/vWqNAJbIy8huDF+zF9bRTOpuRKXSYRGbk6r1qg0Wiwe/duHDx4EKdOnUJBQQF69+6N4ODgxqiPbuJELyJqjmQyGfp3cED/Dg6ISryB/+29hD2xGdh+OhXbT6diSGdHTBvcHn3b2fM/8URUTZ2DbKWBAwdi4MCBDVkL3UblRC8PTvQiomaqd9tW+GZiAGJT8/DlvsvYdioF++IysS8uE73a2mHa4PYI9nWGXM5AS0R6dQ6yn3/+eY3nZTIZ1Go1OnTogHvuuQcKheKui6O/JbFHlohaCF9XW3w+rhfC7uuEr/+Kx8+R1xCdmINn10Sig5M1nrvHGw/3dIfSjJtTErV0MiGEqMsF7dq1Q2ZmJoqKitCqVSsAwI0bN2BpaQlra2tkZGTA29sbe/fuhYeHR6MU3djy8vKg0WiQm5sLW1tbqcsBADzyv0OITszBl0/1xv1+rlKXQ0TUZDLyS7Dq0BX8EHEV+Td3B3O2VWFify881dcTGk6AJWpW6pLD6vzf2Q8++AABAQG4ePEirl+/juvXr+PChQsIDAzEZ599hsTERLi4uODll1+u9xug6gzb03LpLSJqYZxs1HhthA8OzbkXs+/3gZONCul5pfh4ZxyCPgzHW1vPIim7SOoyiUgCde6Rbd++PX755Rf07Nmzyvno6GiMHj0a8fHxOHz4MEaPHo3U1NSGrLXJGFuPbEm5Fj5v7gQAxMy7D3aWSokrIiKSTlmFDr+dTMGKv+JxPi0fACCXASO6uWDygHbo49mKE8OITFhdclidx8impqaioqKi2vmKigrDzl5ubm7Iz8+v663pFip7Y61VZtyfnIhaPKWZfrewR3u74+ClLHx9IB5/XczCjtNp2HE6DV3dbDGpvxce6uEGtTnnaxA1Z3UeWjB06FA899xziI6ONpyLjo7GtGnTcO+99wIATp8+jXbt2jVclS3cP7emZS8DEZGeTCbDoI6OWDMlEDtnDsK4vh5QmclxNiUPs34+hQEf/olFf8QhNZc7hhE1V3UOst9++y3s7e3h7+8PlUoFlUqFPn36wN7eHt9++y0AwNraGosWLWrwYlsqriFLRHR7Pi62WPBodxyZMwyvjfCBm0aN64Vl+OLPSxjw4Z+Y+v0J7IvLgE5Xp9F0RGTk6jxGttL58+dx4cIFAEDnzp3RuXPnBi1MSsY2RnbB77H4an88JvX3wlujukpdDhGR0avQ6rD7XDpWH76CownZhvMe9hZ4sq8nxvRpAwdrlYQVEtGtNOqqBZV8fHwwatQojBo16q5D7LJly+Dl5QW1Wo3AwEAcO3bslm3Pnj2L0aNHw8vLCzKZDEuWLLnrexq7f25PS0REd2amkON+P1dseC4Ie8LuweQBXrBVmyEpuxgf7TyPoAXheG7NCYTHpqNCq5O6XCKqp3rt7HXt2jVs3boViYmJKCsrq/K9xYsX1+leGzZsQFhYGJYvX47AwEAsWbIEISEhiIuLg5OTU7X2RUVF8Pb2xpgxY265xFdd72nsOLSAiKj+OjjZYP5DXfFqiA+2nUrBD0cTcTIpB7vOpmPX2XQ42qjwaC93jOnTBh2cbKQul4jqoM5DC8LDwzFq1Ch4e3vj/Pnz6NatG65cuQIhBHr37o0///yzTgUEBgYiICAAS5cuBQDodDp4eHjghRdewOzZs297rZeXF2bOnImZM2c22D0B4xta4P/ublwvLMP2Fweiq5tG6nKIiExeXFo+Np5IwuboZFwv/LtDxs9dg1E93PBgD1e4avhTMCIpNOrQgjlz5uCVV17B6dOnoVar8csvvyApKQmDBw/GmDFj6nSvsrIyREZGIjg4+O+C5HIEBwcjIiKirqXV+56lpaXIy8urchiLorIKw1+y7JElImoYnV1sMPfBLjjy+jB8Nd4fwb7OUMhlOJ2ci/d3xKL/h39i7FcRWHv0Km4Ult35hkQkiToPLYiNjcWPP/6ov9jMDMXFxbC2tsY777yDhx9+GNOmTav1vbKysqDVauHs7FzlvLOzM86fP1/X0up9zwULFuDtt9+u1+s1tuSbwwps1FxDloiooZkr5Ajp6oKQri64XlCKHadTsfVkCo5fuYGjCdk4mpCNeb+eRWA7e4R0dcF9XZzhZseeWiJjUecga2VlZRgX6+rqisuXL6NrV/1M+qysrIatronMmTMHYWFhhq/z8vLg4eEhYUV/4/hYIqKm0dpahfFBXhgf5IXknGJsO5mCrSdTcDYlD4cvX8fhy9cxf+tZdG+jwfAuzrjXxxm+rjZc35tIQnUOsv369cPBgwfh6+uLBx54AP/9739x+vRpbNq0Cf369avTvRwcHKBQKJCenl7lfHp6OlxcXOpaWr3vWbkerjFKurkZggdXLCAiajLudhZ4bnB7PDe4Pa5eL8Tuc+nYdTYNJ67ewKlruTh1LRcL/7gARxsVBnVwwD2dHDGwowOX9GpA5VodCkoqUFCqPwpLK5BfWoHyCv0qE5X/gZABkMsBG7U5Wlmaw85SCTsLc5gp6r0wE5mQOgfZxYsXo6CgAADw9ttvo6CgABs2bEDHjh3rvGKBUqmEv78/wsPDERoaCkA/MSs8PBwzZsyoa2mNdk8psUeWiEhanq2t8MwgbzwzyBtZBaUIj03HH2fTcfjydWTml2JTdDI2RScDALq42iLQ2x4BXvrD0YbB9t8qtDpk5JciJacYyTnFSMkpQUZ+CTLzS5FVUHrzYxlyi8vv6nVs1WZwtlWjo7M1OjjZoJOzNTo528CrtRWUZgy5zUWdg6y3t7fhcysrKyxfvvyuCggLC8PEiRPRp08f9O3bF0uWLEFhYSEmT54MAJgwYQLc3d2xYMECAPrJXOfOnTN8npycjJiYGFhbW6NDhw61uqcp+ef2tEREJC0HaxXGBrTF2IC2KK3QIvLKDRy4mIUDFzJxLjXPcKw6dAUA0M7BCn08W6G3Zyt0c9Ogk4s1VGYKad9EI9PqBNLySnAtuwhJN4qRlF2EpBtFuJatD65peSXQ1mGHNbW5HNYqM/2hNoNSIYcAULnmkgCg0wnklZTjRmEZ8koqAAB5JRXIKynAxYwCAGmG+5nJZejhYYfBnRxxTydH+LlroJBzeIipqvPyW97e3jh+/Dhat25d5XxOTg569+6N+Pj4OhexdOlSfPLJJ0hLS0PPnj3x+eefIzAwEAAwZMgQeHl5YfXq1QCAK1euoF27dtXuMXjwYOzbt69W97wTY1p+a9TSgzh1LRcrJvTBfV2c73wBERFJIiO/BEfis3E8IRvHr2QjLj0f//4X1kwuQydnG3Rzt0VXNw06OFnD29EKLrZqkxlrq9MJZBaU4toNfTC9dqMISdmVH4uQnFOMcu3to4W5QgYXjRpuGgu421nAyVYNRxsVHG1UcLBWwtFahdbWKtiozWBexyECFVodcorLkVNUhuScElxMz8eF9HxczCjAxfQCFJRWVGlvZ2mOQR0dca+PI0Z0dYWFsnn/R8MU1CWH1TnIyuVypKWlVdtYID09HW3btkVpaWndKzYyxhRke73zB24UleP3lwbB11X6NW2JiKh2covKEZmYjWMJN3AmORdnUnKRU1Tzj8stlQq0c7CCt6M1PO0t4aJRw1WjNoQ9O0vzRg+6Op1AfkkFsovKcL2gFGl5JUjPK0VGXgnS80qQlleClJwSpObeOaiayWVwb2UBj1aW8LC3QJtWlmjTygIe9pZoY2cBB2sV5BL0ggohkJRdjIOX9L3ohy5lIf8fwVZjYY7H/NvgqcC28Ha0bvL6SK8uOazWQwu2bt1q+HzXrl3QaP5emF+r1SI8PBxeXl51r5ZuqaC0Ajdu/qXnzqEFREQmRWNpjnt99KsbAPoQlZxTjDPJeTibkovY1DzEZxbianYRisq0OJuSh7MpNa9jrjSTo5WlOTQWlYcSGgtzWKsUUJrJ9YdCAXMzmf5H7wLQCgGt7u+jXKtDUZkWhaUV+o9l+glUOUXluFFUhhtF5bX+kb9CLoOLrRrudhY3A6sF2thboq29JTzsLeFiqzbKH9fLZDK0bW2JJ1u3xZOBbVGh1SEmKQf74jLx68lkJGUX49uDCfj2YAIGdXTA0/08MczHiRPHjFite2Tlcv1DlMlk+Pcl5ubm8PLywqJFi/Dggw82fJVNzFh6ZOPS8hGy5AA0FuY4OX+4ZHUQEVHjKdfqkJhdhPjMQsRnFuDajWKk5pYgLa8YqTklVXYeawrWKjPYWynhbKuCs6365qH/3FWjD67ONqpmF+60OoEDFzLxw5Gr+DMuwzAspIOTNeaO9MWQzqa3xb2papQeWZ1Ov9xFu3btcPz4cTg4ONxdlXRHSdk3l96yZ28sEVFzZa6Qo72jNdo7WgOoPheipFyLzPxS5BSVI7f47yOnuAzFZVqUVehQWqFDmVaHsgodyrU6yGUyyGUyKOT63lO5TAZzhX7SlKVKASulGSyVClipzGBnaY5WlkrYWylhZ2ne7Cej3YpCLsNQHycM9XFCUnYR1h1LxPpjibiUUYBJq45jSGdHzB3ZBR2cOOTAmNR51YKEhITGqINqYFixwI5LbxERtVRqcwU87C3hYS91JS2Hh70lXhvhg+cHt8fSPy9i9eEr2BeXiYMXD+Dpfp6YGdwRdpZKqcsk1DLIfv7557W+4YsvvljvYqiqv9eQZY8sERFRU9NYmOONkV3wZKAn3t9+DntiM7D68BVsiUnGJ4/14GpCRqBWQfbTTz+t1c1kMhmDbANikCUiIpJeOwcrfDMxAH9dzMS7287hQnoBpn5/AlMHtcOrI3zqvEQYNZxaBVkOJ5CGYXtaew4tICIiktqgjo7Y9sIgfPj7eaw8lIAVfyUg8uoNLH2yN9zs2Okkhbv6L4QQotoKBtRwuD0tERGRcVGayTHvoS5Y/rQ/bNRmiErMwcjP/8LeuAypS2uR6hVkv//+e/j5+cHCwgIWFhbo3r071qxZ09C1tWh5JeWGfaa5hiwREZFxGdHNBdtfGIRu7ra4UVSOyauOY8meC+zga2J1DrKLFy/GtGnT8MADD+Cnn37CTz/9hBEjRuD555+v9VhaurNr2fre2FaW5rBW1XlxCSIiImpkbVtb4ufn+2N8P08AwJI9F/He9liG2SZU54T0xRdf4Msvv8SECRMM50aNGoWuXbvirbfewssvv9ygBbZU1zg+loiIyOipzRV4N7QbOjlb481fz+LbgwkordDinVHdJNmGt6Wpc49samoq+vfvX+18//79kZqa2iBFEVcsICIiMiXjg7zw8ejukMmAH44kYvamU7Xe8pfqr85BtkOHDvjpp5+qnd+wYQM6duzYIEURJ3oRERGZmscDPPDp4z0hlwE/nbiGsJ9iUKHVSV1Ws1bnoQVvv/02xo4diwMHDmDAgAEAgEOHDiE8PLzGgEv1k5KjD7JuGrXElRAREVFthfZyh7lCjpfWR+PXmBSUVejw2RO9oDTjWrONoda/qmfOnAEAjB49GkePHoWDgwO2bNmCLVu2wMHBAceOHcMjjzzSaIW2NGl5JQAAFw2HFhAREZmSkd1d8eXT/lAq5Pj9TBrmbjnNCWCNpNY9st27d0dAQACeeeYZPPHEE/jhhx8as64WL90QZNkjS0REZGru6+KML5/ujanfn8BPJ66hs4stpgxsJ3VZzU6te2T379+Prl274r///S9cXV0xadIk/PXXX41ZW4ul1Qlk5JcCAFxsGWSJiIhM0TBfZ7z+gC8A4P3t57D/QqbEFTU/tQ6ygwYNwsqVK5GamoovvvgCCQkJGDx4MDp16oSPPvoIaWlpjVlni3K9oBRanYBcBjhYK6Uuh4iIiOppysB2GOPfBjoBzFgXhUsZBVKX1KzUeeSxlZUVJk+ejP379+PChQsYM2YMli1bhrZt22LUqFGNUWOLUzk+1tFGBTMFB4cTERGZKplMhvce6YY+nq2QX1KBZ747jpyiMqnLajbuKiV16NABr7/+OubOnQsbGxts3769oepq0dJyb46P5bACIiIik6cyU2D5eH+421ngyvUiTF8XhXIuy9Ug6h1kDxw4gEmTJsHFxQWzZs3Co48+ikOHDjVkbS1W5UQvZwZZIiKiZsHBWoUVE/rAUqnAoUvX8f72WKlLahbqFGRTUlLwwQcfoFOnThgyZAguXbqEzz//HCkpKVixYgX69evXWHW2KGlcsYCIiKjZ6eJmi0/H9gQArD58BXvjMqQtqBmodZC9//774enpiS+++AKPPPIIYmNjcfDgQUyePBlWVlaNWWOLk5arX7GAPbJERETNS0hXF8MyXLN/OYXconKJKzJttQ6y5ubm+Pnnn3Ht2jV89NFH6Ny5c2PW1aKl5el39eIYWSIiouZnVkhneDtaIT2vFG/9dlbqckxarYPs1q1b8fDDD0OhUDRmPYR/TPbi0AIiIqJmR22uwKIxPSCXAZujk7HrLJcwrS+u7WSE0vM4tICIiKg569W2FZ4b3B4A8Mbm08gu5JJc9cEga2QKSitQUFoBgD2yREREzdnM4I7o7GyDrIIyvLnljNTlmCQGWSNTOazAWmUGa5WZxNUQERFRY1GZKbDo8R4wk8uw/XQqfjuZInVJJodB1sj8vYasSuJKiIiIqLF1c9dg+tAOAIA3fz2DjPwSiSsyLQyyRoYTvYiIiFqWGfd2QFc3W+QUleMDbpRQJ0YRZJctWwYvLy+o1WoEBgbi2LFjt22/ceNG+Pj4QK1Ww8/PDzt27Kjy/YKCAsyYMQNt2rSBhYUFunTpguXLlzfmW2gwadzVi4iIqEUxV8jx4aPdAQBbYlJwMilH2oJMiORBdsOGDQgLC8P8+fMRFRWFHj16ICQkBBkZNe92cfjwYYwbNw5TpkxBdHQ0QkNDERoaijNn/h4kHRYWhp07d+KHH35AbGwsZs6ciRkzZmDr1q1N9bbqrXJoAdeQJSIiajn82mjwaC93AMD722MhhJC4ItMgeZBdvHgxpk6dismTJxt6Ti0tLbFy5coa23/22WcYMWIEZs2aBV9fX7z77rvo3bs3li5damhz+PBhTJw4EUOGDIGXlxeeffZZ9OjR4449vcaAQwuIiIhapldCOkNtLsexK9lcW7aWJA2yZWVliIyMRHBwsOGcXC5HcHAwIiIiarwmIiKiSnsACAkJqdK+f//+2Lp1K5KTkyGEwN69e3HhwgUMHz68cd5IA0rn0AIiIqIWyc3OAs8O8gYALPj9PMoqdBJXZPwkDbJZWVnQarVwdnauct7Z2RlpaTX/TyQtLe2O7b/44gt06dIFbdq0gVKpxIgRI7Bs2TLcc889Nd6ztLQUeXl5VQ6ppHFoARERUYv13OD2cLRR4er1InwfcUXqcoye5EMLGsMXX3yBI0eOYOvWrYiMjMSiRYswffp07Nmzp8b2CxYsgEajMRweHh5NXLFehVaHzHz9rl4cWkBERNTyWKnM8MrwTgCAz8Mv4gZ3/LotSYOsg4MDFAoF0tPTq5xPT0+Hi4tLjde4uLjctn1xcTFef/11LF68GA899BC6d++OGTNmYOzYsVi4cGGN95wzZw5yc3MNR1JSUgO8u7rLKiiDTgAKuQwO1lxHloiIqCV6zN8DPi42yCupwOd/XpS6HKMmaZBVKpXw9/dHeHi44ZxOp0N4eDiCgoJqvCYoKKhKewDYvXu3oX15eTnKy8shl1d9awqFAjpdzWNNVCoVbG1tqxxSqBxW4GitgkIuk6QGIiIikpZCLsPckV0AAGsiriI+s0DiioyX5EMLwsLCsGLFCnz33XeIjY3FtGnTUFhYiMmTJwMAJkyYgDlz5hjav/TSS9i5cycWLVqE8+fP46233sKJEycwY8YMAICtrS0GDx6MWbNmYd++fUhISMDq1avx/fff45FHHpHkPdZW5YoFzhxWQERE1KIN7OiAe32cUKETWPD7eanLMVpmUhcwduxYZGZmYt68eUhLS0PPnj2xc+dOw4SuxMTEKr2r/fv3x7p16zB37ly8/vrr6NixI7Zs2YJu3boZ2qxfvx5z5szBU089hezsbHh6euL999/H888/3+Tvry7+XkOWwwqIiIhautcf8MH+C5nYfS4dp6/lwq+NRuqSjI5McMXdavLy8qDRaJCbm9ukwww+2nkeX+67jIlBnnj74W53voCIiIiatbANMdgUnYz7u7ngy6f9pS6nSdQlh0k+tID+ls6hBURERPQPzw9pDwDYeTYNlzI4VvbfGGSNCNeQJSIion/q5GyD+7o4Qwjgq/2XpS7H6DDIGhEGWSIiIvq3/9zsld0cnYyUnGKJqzEuDLJGhEMLiIiI6N96tW2FIO/WqNAJrPgrXupyjAqDrJHILylHYZkWAHtkiYiIqKr/DNX3yq4/loRs7vZlwCBrJCqX3rJRmcFKJfmqaERERGREBnZwQDd3WxSXa7H6UILU5RgNBlkjkZZbCoDDCoiIiKg6mUyG/wzpAABYffgKCkorJK7IODDIGglO9CIiIqLbCenqAm8HK+SVVGDd0atSl2MUGGSNROXQAmcGWSIiIqqBQi7D84P1Y2W/+SsBpRVaiSuSHoOskUi7uWKBi4bb0xIREVHNQnu5w1WjRkZ+KTZFJUtdjuQYZI2EYWiBxkLiSoiIiMhYKc3kmDKwHQDgu8NXIISQuCJpMcgaiXSOkSUiIqJaGOPvAZWZHOfT8hGdlCN1OZJikDUShqEFDLJERER0GxpLc4zs7goAWHc0UeJqpMUgawQqtDpkFVQuv8UxskRERHR7TwW2BQBsO5WC3OJyiauRDoOsEcgsKIVOAGZyGRysGGSJiIjo9nq3bYXOzjYoKddhc9Q1qcuRDIOsEagcVuBko4JcLpO4GiIiIjJ2MpkMT97slV13LLHFTvpikDUChjVkuasXERER1VJoL3eozeW4kF6AqMQbUpcjCQZZI8CJXkRERFRXGgtzPNTdDQCwtoVO+mKQNQKp3NWLiIiI6qFyeMH2U6nILWp5k74YZI1AumFXLwZZIiIiqr2eHnbwdbVFaYUOv7TASV8MskYgjZshEBERUT209ElfDLJGID3v5hqyDLJERERUR6E93WCpVOBSRgGOX2lZk74YZCUmhPh7sheHFhAREVEd2ajNMaqHftLXuqNXJa6maTHISiyvpALF5VoAHFpARERE9VM5vGDHmTTkFJVJXE3TYZCVWOUasrZqM1goFRJXQ0RERKaoexv9pK+yCh12nkmTupwmwyArMaVCjkd7u+P+bq5Sl0JEREQmrHJ4wdaTKRJX0nQYZCXm5WCFxY/3xEePdZe6FCIiIjJhD3bXd4pFxF9Hxs2f+DZ3DLJEREREzYCHvSV6t7WDEMD206lSl9MkGGSJiIiImomHWtjwAgZZIiIiomZiZHdXyGVAdGIOkrKLpC6n0THIEhERETUTTjZq9PNuDQD47VTz75U1iiC7bNkyeHl5Qa1WIzAwEMeOHbtt+40bN8LHxwdqtRp+fn7YsWNHtTaxsbEYNWoUNBoNrKysEBAQgMTExMZ6C0RERERGoXL1gt9ONv9xspIH2Q0bNiAsLAzz589HVFQUevTogZCQEGRkZNTY/vDhwxg3bhymTJmC6OhohIaGIjQ0FGfOnDG0uXz5MgYOHAgfHx/s27cPp06dwptvvgm1mhsOEBERUfM2opsLzOQyxKbm4VJGvtTlNCqZEEJIWUBgYCACAgKwdOlSAIBOp4OHhwdeeOEFzJ49u1r7sWPHorCwENu2bTOc69evH3r27Inly5cDAJ544gmYm5tjzZo19aopLy8PGo0Gubm5sLW1rdc9iIiIiKTyf6uP48/zGXhxWEeE3ddJ6nLqpC45TNIe2bKyMkRGRiI4ONhwTi6XIzg4GBERETVeExERUaU9AISEhBja63Q6bN++HZ06dUJISAicnJwQGBiILVu23LKO0tJS5OXlVTmIiIiITNXfwwtSIHGfZaOSNMhmZWVBq9XC2dm5ynlnZ2ekpdW8vVpaWtpt22dkZKCgoAAffvghRowYgT/++AOPPPIIHn30Uezfv7/Gey5YsAAajcZweHh4NMC7IyIiIpJGcBdnqMzkSMgqxNmU5ttBJ/kY2Yam0+kAAA8//DBefvll9OzZE7Nnz8aDDz5oGHrwb3PmzEFubq7hSEpKasqSiYiIiBqUtcoMwb76jr/mvKaspEHWwcEBCoUC6enpVc6np6fDxcWlxmtcXFxu297BwQFmZmbo0qVLlTa+vr63XLVApVLB1ta2ykFERERkyh7qod+ydtvJFOh0zXN4gaRBVqlUwt/fH+Hh4YZzOp0O4eHhCAoKqvGaoKCgKu0BYPfu3Yb2SqUSAQEBiIuLq9LmwoUL8PT0bOB3QERERGSchnR2grXKDCm5JYhMvCF1OY3CTOoCwsLCMHHiRPTp0wd9+/bFkiVLUFhYiMmTJwMAJkyYAHd3dyxYsAAA8NJLL2Hw4MFYtGgRRo4cifXr1+PEiRP4+uuvDfecNWsWxo4di3vuuQdDhw7Fzp078dtvv2Hfvn1SvEUiIiKiJqc2V2B4V2dsikrGbydTEOBlL3VJDU7yMbJjx47FwoULMW/ePPTs2RMxMTHYuXOnYUJXYmIiUlP/XtC3f//+WLduHb7++mv06NEDP//8M7Zs2YJu3boZ2jzyyCNYvnw5Pv74Y/j5+eGbb77BL7/8goEDBzb5+yMiIiKSyoPd9cMLdp9Lb5arF0i+jqwx4jqyRERE1ByUlGvR850/UFKuw/YXB6Krm0bqku7IZNaRJSIiIqLGozZXYGAHRwBAeGzNu6aaMgZZIiIiomYs2NcJABAem36HlqaHQZaIiIioGbvXRx9kT17LRUZ+icTVNCwGWSIiIqJmzMlWje5t9GNj955vXsMLGGSJiIiImrlhPvrVoPY0s3GyDLJEREREzdywm+NkD17MQkm5VuJqGg6DLBEREVEz19XNFi62ahSXaxERf13qchoMgywRERFRMyeTyXBvM1y9gEGWiIiIqAWoXIbrz9iMZrPLF4MsERERUQvQv70D1OZypOSW4FxqntTlNAgGWSIiIqIWQL/LlwMAfa9sc8AgS0RERNRCDPO9uQxXM1lPlkGWiIiIqIUYVrnLV1JOs9jli0GWiIiIqIX45y5f+85nSlzN3WOQJSIiImpB7r3ZK7unGSzDxSBLRERE1IIE3xwn+1cz2OWLQZaIiIioBfnnLl/HErKlLueuMMgSERERtSAymQwDbi7DdehylsTV3B0GWSIiIqIWZkCH1gCAw5euS1zJ3WGQJSIiImphKntkz6TkIqeoTOJq6o9BloiIiKiFcbZVo4OTNYQAjsSbbq8sgywRERFRCzSgvX54wSETHl7AIEtERETUAvVvBhO+GGSJiIiIWqB+3q0hlwHxmYVIyzXN7WoZZImIiIhaII2FOfzc9dvVHrpkmr2yDLJERERELZSpDy9gkCUiIiJqoQa0vxlkL2VBCCFxNXXHIEtERETUQvXxagWlmRzpeaW4nFkodTl1xiBLRERE1EKpzRXwb9sKAHDYBIcXMMgSERERtWCV29Wa4oQvBlkiIiKiFqxywlfE5evQ6kxrnKxRBNlly5bBy8sLarUagYGBOHbs2G3bb9y4ET4+PlCr1fDz88OOHTtu2fb555+HTCbDkiVLGrhqIiIiItPX3V0DG5UZ8koqcDYlV+py6kTyILthwwaEhYVh/vz5iIqKQo8ePRASEoKMjIwa2x8+fBjjxo3DlClTEB0djdDQUISGhuLMmTPV2m7evBlHjhyBm5tbY78NIiIiIpNkppAj0NsegOltVyt5kF28eDGmTp2KyZMno0uXLli+fDksLS2xcuXKGtt/9tlnGDFiBGbNmgVfX1+8++676N27N5YuXVqlXXJyMl544QWsXbsW5ubmTfFWiIiIiEzSgJvDC0xtwpekQbasrAyRkZEIDg42nJPL5QgODkZERESN10RERFRpDwAhISFV2ut0OowfPx6zZs1C165d71hHaWkp8vLyqhxERERELUVlkD1+JRulFVqJq6k9SYNsVlYWtFotnJ2dq5x3dnZGWlpajdekpaXdsf1HH30EMzMzvPjii7WqY8GCBdBoNIbDw8Ojju+EiIiIyHR1dLKGo40KJeU6RF3NkbqcWpN8aEFDi4yMxGeffYbVq1dDJpPV6po5c+YgNzfXcCQlJTVylURERETGQyaToX97/TJcpjS8QNIg6+DgAIVCgfT09Crn09PT4eLiUuM1Li4ut23/119/ISMjA23btoWZmRnMzMxw9epV/Pe//4WXl1eN91SpVLC1ta1yEBEREbUkldvVHr5sOhO+JA2ySqUS/v7+CA8PN5zT6XQIDw9HUFBQjdcEBQVVaQ8Au3fvNrQfP348Tp06hZiYGMPh5uaGWbNmYdeuXY33ZoiIiIhMWN92+pULTl/LRUm5aYyTNZO6gLCwMEycOBF9+vRB3759sWTJEhQWFmLy5MkAgAkTJsDd3R0LFiwAALz00ksYPHgwFi1ahJEjR2L9+vU4ceIEvv76awBA69at0bp16yqvYW5uDhcXF3Tu3Llp3xwRERGRifBsbQkHayWyCspwOjkXAV72Upd0R5IH2bFjxyIzMxPz5s1DWloaevbsiZ07dxomdCUmJkIu/7vjuH///li3bh3mzp2L119/HR07dsSWLVvQrVs3qd4CERERkcmTyWTw92yFXWfTceLKDZMIsjIhhGntRdYE8vLyoNFokJuby/GyRERE1GKsOBCP93fEItjXCd9MDJCkhrrksGa3agERERER1Y+/VysAQOTVGzCFvk4GWSIiIiICAHRz00BlJseNonJcziyUupw7YpAlIiIiIgCA0kyOHh52AIDIq9nSFlMLDLJEREREZNDH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Y/jw4XBycsLRo0eRmZkJX19flJSUYNeuXYiLi0Pr1q2h0Wjw1FNPYf78+Zg4cSLeeustZGZm4oUXXsD48eMNP77/J7Vajddeew2vvvoqlEolBgwYgMzMTJw9exZTpkypV82zZs3C448/jl69eiE4OBi//fYbNm3ahD179tzVr8W8efPw4IMPom3btnjssccgl8tx8uRJnDlzBu+99x4A/coF4eHhGDBgAFQqFVq1anXbez755JN45ZVXsGLFCnz//fd3VR8RtUzskSUiugVbW1scOHAADzzwADp16oS5c+di0aJFuP/++zF16lR07twZffr0gaOjIw4dOgRLS0vs2rUL2dnZCAgIwGOPPYZhw4Zh6dKlt3yNN998E//9738xb948+Pr6YuzYsbcc/1oboaGh+Oyzz7Bw4UJ07doVX331FVatWoUhQ4bU+54AEBISgm3btuGPP/5AQEAA+vXrh08//RSenp6GNosWLcLu3bvh4eGBXr163fGeGo0Go0ePhrW1db02lyAikgkhhNRFEBFRyzRs2DB07doVn3/+udSlEJEJYpAlIqImd+PGDezbtw+PPfYYzp07V+MYYiKiO+EYWSIianK9evXCjRs38NFHHzHEElG9sUeWiIiIiEwSJ3sRERERkUlikCUiIiIik8QgS0REREQmiUGWiIiIiEwSgywRERERmSQGWSIiIiIySQyyRERERGSSGGSJiIiIyCQxyBIRERGRSfp/7rwmLZVWW4cAAAAASUVORK5CYII=", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import numpy as np\n", + "sto_array = pybamm.Array(np.linspace(0,1,101))\n", + "sto = sto_array.entries\n", + "\n", + "ocp_avg_values = ocp_avg(sto_array).evaluate()\n", + "ocp_lithiation_values = lithiation_ocp(sto_array).evaluate()\n", + "ocp_delithiation_values = delithiation_ocp(sto_array).evaluate()\n", "\n", - "model = pybamm.lithium_ion.SPM(\n", + "hysteresis_values = hysteresis(sto_array).evaluate()\n", + "plt.subplots(2,1,sharex=True,figsize=(7,8))\n", + "plt.subplot(2,1,1)\n", + "plt.plot(sto, ocp_avg_values, label=\"OCP average\")\n", + "plt.plot(sto, ocp_lithiation_values, label=\"OCP lithiation\")\n", + "plt.plot(sto, ocp_delithiation_values, label=\"OCP delithiation\")\n", + "plt.ylabel(\"Voltage [V]\")\n", + "plt.legend()\n", + "plt.subplot(2,1,2)\n", + "plt.plot(sto, hysteresis_values, label=\"OCP hysteresis\")\n", + "plt.xlabel(\"stoichiometry\")\n", + "plt.ylabel(\"Voltage [V]\")\n", + "plt.legend()\n", + "plt.tight_layout()\n", + "plt.show()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Next, we need to add the additional parameters required by the model" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "parameters_DCHS.update(\n", " {\n", - " \"open-circuit potential\": ((\"single\", \"current sigmoid\"), \"single\"),\n", - " \"particle phases\": (\"2\", \"1\"),\n", - " }\n", + " \"Secondary: Negative particle hysteresis decay rate\": 0.005,\n", + " \"Secondary: Negative particle hysteresis switching factor\": 10,\n", + " },\n", + " check_already_exists=False,\n", ")\n", "\n", "\n", @@ -157,75 +209,79 @@ " (\"Discharge at 1 C for 1 hour or until 2.5 V\", \"Rest for 15 minutes\"),\n", " (\n", " \"Charge at 1C until 4.2 V\",\n", - " \"Hold at 4.2 V until 50 mA\",\n", + " \"Hold at 4.2 V until 0.05 C\",\n", " \"Rest for 15 minutes\",\n", " ),\n", " ]\n", ")\n", "\n", "\n", - "simulation = pybamm.Simulation(\n", - " model, experiment=experiment, parameter_values=parameters\n", + "simulation_dchs = pybamm.Simulation(\n", + " model_DCHS, experiment=experiment, parameter_values=parameters_DCHS\n", + ")\n", + "solution_dchs = simulation_dchs.solve(calc_esoh=False)\n", + "\n", + "simulation_current_sigmoid = pybamm.Simulation(\n", + " model_current_sigmoid, experiment=experiment, parameter_values=parameters_current_sigmoid\n", ")\n", - "solution_sigmoid = simulation.solve(calc_esoh=False)" + "\n", + "solution_current_sigmoid = simulation_current_sigmoid.solve(calc_esoh=False)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now plotting the results and the hysteresis state " ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "b61b1d1b47314d43962ab8968639d569", + "model_id": "2dc1c68398924dafad346326317839db", "version_major": 2, "version_minor": 0 }, "text/plain": [ - "interactive(children=(FloatSlider(value=0.0, description='t', max=3.3455896030671757, step=0.03345589603067175…" + "interactive(children=(FloatSlider(value=0.0, description='t', max=3.149265739087976, step=0.03149265739087976)…" ] }, "metadata": {}, "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" } ], "source": [ - "solution_sigmoid.plot(\n", - " [\n", - " # \"X-averaged negative electrode secondary hysteresis state\",\n", - " # \"Negative electrode secondary hysteresis state\",\n", + "\n", + "output_variables = [\n", + " \"X-averaged negative electrode secondary hysteresis state\",\n", " \"Negative electrode secondary open-circuit potential [V]\",\n", + " \"Negative electrode secondary stoichiometry\",\n", " \"Terminal voltage [V]\",\n", " \"X-averaged negative electrode secondary open-circuit potential [V]\",\n", " ]\n", - ")" + "\n", + "pybamm.QuickPlot(solution_dchs, output_variables=output_variables).dynamic_plot()\n" ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "b5db2821f7ab4da2979b66e5ff078d61", + "model_id": "0de9e59cc56d475cbb49b772442f3ed8", "version_major": 2, "version_minor": 0 }, "text/plain": [ - "interactive(children=(FloatSlider(value=0.0, description='t', max=3.3455896030671757, step=0.03345589603067175…" + "interactive(children=(FloatSlider(value=0.0, description='t', max=3.149265739087976, step=0.03149265739087976)…" ] }, "metadata": {}, @@ -233,15 +289,13 @@ } ], "source": [ - "pybamm.QuickPlot(\n", - " [solution, solution_sigmoid],\n", - " labels=[\"DCHS\", \"Sigmoid\"],\n", - " output_variables=[\n", - " \"Negative electrode secondary open-circuit potential [V]\",\n", - " \"Terminal voltage [V]\",\n", - " \"X-averaged negative electrode secondary open-circuit potential [V]\",\n", - " ],\n", - ").dynamic_plot()" + "\n", + "output_variables = [\n", + " \"Terminal voltage [V]\",\n", + " \"Current [A]\",\n", + " \"Negative electrode secondary open-circuit potential [V]\",\n", + "]\n", + "pybamm.QuickPlot([solution_current_sigmoid,solution_dchs], labels=['Current sigmoid','DCHS'], output_variables=output_variables).dynamic_plot()" ] } ], From cc64fb4949e0739db19b55cebcf8a9e54d94de27 Mon Sep 17 00:00:00 2001 From: Tanner Leo Date: Thu, 18 Apr 2024 17:55:54 -0700 Subject: [PATCH 25/43] compatabilize composite model --- .../interface/open_circuit_potential/dchs_ocp.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/pybamm/models/submodels/interface/open_circuit_potential/dchs_ocp.py b/pybamm/models/submodels/interface/open_circuit_potential/dchs_ocp.py index 66a1ed8395..e8992f7f67 100644 --- a/pybamm/models/submodels/interface/open_circuit_potential/dchs_ocp.py +++ b/pybamm/models/submodels/interface/open_circuit_potential/dchs_ocp.py @@ -128,11 +128,17 @@ def get_coupled_variables(self, variables): def set_rhs(self, variables): domain, Domain = self.domain_Domain phase_name = self.phase_name + phase = self.phase current = variables[ f"{Domain} electrode {phase_name}interfacial current density [A.m-2]" ] - Q_cell = variables[f"{Domain} electrode {phase_name}capacity [A.h]"] + # check if composite or not + if phase_name != '': + Q_cell = variables[f"{Domain} electrode {phase_name}phase capacity [A.h]"] + else: + Q_cell = variables[f"{Domain} electrode capacity [A.h]"] + dQdU = variables[ f"{Domain} electrode {phase_name}differential capacity [A.s.V-1]" ] From 7952dbdc5717b6ae19a39b19910528499f27fc96 Mon Sep 17 00:00:00 2001 From: Tanner Leo Date: Thu, 18 Apr 2024 17:55:58 -0700 Subject: [PATCH 26/43] add test --- .../test_full_battery_models/test_lithium_ion/test_dfn.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_dfn.py b/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_dfn.py index 76384f8306..e19f9f1048 100644 --- a/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_dfn.py +++ b/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_dfn.py @@ -42,6 +42,13 @@ def test_well_posed_dchs_ocp_with_psd(self): } self.check_well_posedness(options) + def test_well_posed_dchs_ocp_with_composite(self): + options = { + "open-circuit potential": (("DCHS",'single'),'single'), + "particle phases": ('2','1'), + } + self.check_well_posedness(options) + def test_well_posed_external_circuit_explicit_power(self): options = {"operating mode": "explicit power"} self.check_well_posedness(options) From 0ad186907b60e9587767b87ad4380a5dcc363c9b Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 19 Apr 2024 00:56:11 +0000 Subject: [PATCH 27/43] style: pre-commit fixes --- .../examples/notebooks/models/DCHS.ipynb | 38 ++++++++++--------- .../open_circuit_potential/dchs_ocp.py | 2 +- .../test_lithium_ion/test_dfn.py | 4 +- 3 files changed, 24 insertions(+), 20 deletions(-) diff --git a/docs/source/examples/notebooks/models/DCHS.ipynb b/docs/source/examples/notebooks/models/DCHS.ipynb index 248a59504c..02b3007f95 100644 --- a/docs/source/examples/notebooks/models/DCHS.ipynb +++ b/docs/source/examples/notebooks/models/DCHS.ipynb @@ -102,7 +102,6 @@ "metadata": {}, "outputs": [], "source": [ - "\n", "parameters_DCHS = pybamm.ParameterValues(\"Chen2020_composite\")\n", "parameters_current_sigmoid = pybamm.ParameterValues(\"Chen2020_composite\")\n", "\n", @@ -158,7 +157,8 @@ ], "source": [ "import numpy as np\n", - "sto_array = pybamm.Array(np.linspace(0,1,101))\n", + "\n", + "sto_array = pybamm.Array(np.linspace(0, 1, 101))\n", "sto = sto_array.entries\n", "\n", "ocp_avg_values = ocp_avg(sto_array).evaluate()\n", @@ -166,20 +166,20 @@ "ocp_delithiation_values = delithiation_ocp(sto_array).evaluate()\n", "\n", "hysteresis_values = hysteresis(sto_array).evaluate()\n", - "plt.subplots(2,1,sharex=True,figsize=(7,8))\n", - "plt.subplot(2,1,1)\n", + "plt.subplots(2, 1, sharex=True, figsize=(7, 8))\n", + "plt.subplot(2, 1, 1)\n", "plt.plot(sto, ocp_avg_values, label=\"OCP average\")\n", "plt.plot(sto, ocp_lithiation_values, label=\"OCP lithiation\")\n", "plt.plot(sto, ocp_delithiation_values, label=\"OCP delithiation\")\n", "plt.ylabel(\"Voltage [V]\")\n", "plt.legend()\n", - "plt.subplot(2,1,2)\n", + "plt.subplot(2, 1, 2)\n", "plt.plot(sto, hysteresis_values, label=\"OCP hysteresis\")\n", "plt.xlabel(\"stoichiometry\")\n", "plt.ylabel(\"Voltage [V]\")\n", "plt.legend()\n", "plt.tight_layout()\n", - "plt.show()\n" + "plt.show()" ] }, { @@ -222,7 +222,9 @@ "solution_dchs = simulation_dchs.solve(calc_esoh=False)\n", "\n", "simulation_current_sigmoid = pybamm.Simulation(\n", - " model_current_sigmoid, experiment=experiment, parameter_values=parameters_current_sigmoid\n", + " model_current_sigmoid,\n", + " experiment=experiment,\n", + " parameter_values=parameters_current_sigmoid,\n", ")\n", "\n", "solution_current_sigmoid = simulation_current_sigmoid.solve(calc_esoh=False)" @@ -256,16 +258,15 @@ } ], "source": [ - "\n", "output_variables = [\n", - " \"X-averaged negative electrode secondary hysteresis state\",\n", - " \"Negative electrode secondary open-circuit potential [V]\",\n", - " \"Negative electrode secondary stoichiometry\",\n", - " \"Terminal voltage [V]\",\n", - " \"X-averaged negative electrode secondary open-circuit potential [V]\",\n", - " ]\n", + " \"X-averaged negative electrode secondary hysteresis state\",\n", + " \"Negative electrode secondary open-circuit potential [V]\",\n", + " \"Negative electrode secondary stoichiometry\",\n", + " \"Terminal voltage [V]\",\n", + " \"X-averaged negative electrode secondary open-circuit potential [V]\",\n", + "]\n", "\n", - "pybamm.QuickPlot(solution_dchs, output_variables=output_variables).dynamic_plot()\n" + "pybamm.QuickPlot(solution_dchs, output_variables=output_variables).dynamic_plot()" ] }, { @@ -289,13 +290,16 @@ } ], "source": [ - "\n", "output_variables = [\n", " \"Terminal voltage [V]\",\n", " \"Current [A]\",\n", " \"Negative electrode secondary open-circuit potential [V]\",\n", "]\n", - "pybamm.QuickPlot([solution_current_sigmoid,solution_dchs], labels=['Current sigmoid','DCHS'], output_variables=output_variables).dynamic_plot()" + "pybamm.QuickPlot(\n", + " [solution_current_sigmoid, solution_dchs],\n", + " labels=[\"Current sigmoid\", \"DCHS\"],\n", + " output_variables=output_variables,\n", + ").dynamic_plot()" ] } ], diff --git a/pybamm/models/submodels/interface/open_circuit_potential/dchs_ocp.py b/pybamm/models/submodels/interface/open_circuit_potential/dchs_ocp.py index e8992f7f67..bfa227e212 100644 --- a/pybamm/models/submodels/interface/open_circuit_potential/dchs_ocp.py +++ b/pybamm/models/submodels/interface/open_circuit_potential/dchs_ocp.py @@ -134,7 +134,7 @@ def set_rhs(self, variables): f"{Domain} electrode {phase_name}interfacial current density [A.m-2]" ] # check if composite or not - if phase_name != '': + if phase_name != "": Q_cell = variables[f"{Domain} electrode {phase_name}phase capacity [A.h]"] else: Q_cell = variables[f"{Domain} electrode capacity [A.h]"] diff --git a/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_dfn.py b/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_dfn.py index e19f9f1048..76c78aab8a 100644 --- a/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_dfn.py +++ b/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_dfn.py @@ -44,8 +44,8 @@ def test_well_posed_dchs_ocp_with_psd(self): def test_well_posed_dchs_ocp_with_composite(self): options = { - "open-circuit potential": (("DCHS",'single'),'single'), - "particle phases": ('2','1'), + "open-circuit potential": (("DCHS", "single"), "single"), + "particle phases": ("2", "1"), } self.check_well_posedness(options) From 9e46865ab16e83a2e9d3872df067d613a6718867 Mon Sep 17 00:00:00 2001 From: Tanner Leo Date: Thu, 18 Apr 2024 17:59:43 -0700 Subject: [PATCH 28/43] remove unessesary statements --- .../interface/open_circuit_potential/dchs_ocp.py | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/pybamm/models/submodels/interface/open_circuit_potential/dchs_ocp.py b/pybamm/models/submodels/interface/open_circuit_potential/dchs_ocp.py index bfa227e212..2f5b5d09a5 100644 --- a/pybamm/models/submodels/interface/open_circuit_potential/dchs_ocp.py +++ b/pybamm/models/submodels/interface/open_circuit_potential/dchs_ocp.py @@ -103,14 +103,6 @@ def get_coupled_variables(self, variables): # must be DFN with PSD model elif f"{domain} electrode" in sto_surf.domains["secondary"]: ocp_surf = ocp_surf_eq + H * h - else: - raise ValueError( - 'Model type not implementted with open-circuit potential as "DCHS"' - ) - else: - raise ValueError( - 'Model type not implementted with open-circuit potential as "DCHS"' - ) # must not be a psd else: ocp_surf = ocp_surf_eq + H * h @@ -134,7 +126,7 @@ def set_rhs(self, variables): f"{Domain} electrode {phase_name}interfacial current density [A.m-2]" ] # check if composite or not - if phase_name != "": + if phase_name != '': Q_cell = variables[f"{Domain} electrode {phase_name}phase capacity [A.h]"] else: Q_cell = variables[f"{Domain} electrode capacity [A.h]"] From 746f8115fdcdc4dce66e524966e4130b7555aef1 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 19 Apr 2024 00:59:56 +0000 Subject: [PATCH 29/43] style: pre-commit fixes --- .../submodels/interface/open_circuit_potential/dchs_ocp.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pybamm/models/submodels/interface/open_circuit_potential/dchs_ocp.py b/pybamm/models/submodels/interface/open_circuit_potential/dchs_ocp.py index 2f5b5d09a5..061a938dc7 100644 --- a/pybamm/models/submodels/interface/open_circuit_potential/dchs_ocp.py +++ b/pybamm/models/submodels/interface/open_circuit_potential/dchs_ocp.py @@ -126,7 +126,7 @@ def set_rhs(self, variables): f"{Domain} electrode {phase_name}interfacial current density [A.m-2]" ] # check if composite or not - if phase_name != '': + if phase_name != "": Q_cell = variables[f"{Domain} electrode {phase_name}phase capacity [A.h]"] else: Q_cell = variables[f"{Domain} electrode capacity [A.h]"] From e9dd55f92739f2f7b4a8cfdf01a841768bf2b959 Mon Sep 17 00:00:00 2001 From: Tanner Leo Date: Thu, 18 Apr 2024 18:00:48 -0700 Subject: [PATCH 30/43] remove unused --- .../submodels/interface/open_circuit_potential/dchs_ocp.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pybamm/models/submodels/interface/open_circuit_potential/dchs_ocp.py b/pybamm/models/submodels/interface/open_circuit_potential/dchs_ocp.py index 061a938dc7..3c86d54751 100644 --- a/pybamm/models/submodels/interface/open_circuit_potential/dchs_ocp.py +++ b/pybamm/models/submodels/interface/open_circuit_potential/dchs_ocp.py @@ -120,7 +120,6 @@ def get_coupled_variables(self, variables): def set_rhs(self, variables): domain, Domain = self.domain_Domain phase_name = self.phase_name - phase = self.phase current = variables[ f"{Domain} electrode {phase_name}interfacial current density [A.m-2]" From d379fb7480215de448b7fb120eff42b0e20192a2 Mon Sep 17 00:00:00 2001 From: Tanner Leo Date: Tue, 30 Apr 2024 16:51:52 -0700 Subject: [PATCH 31/43] pre-compatibilize psd+composite electrode model --- .../submodels/interface/open_circuit_potential/dchs_ocp.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pybamm/models/submodels/interface/open_circuit_potential/dchs_ocp.py b/pybamm/models/submodels/interface/open_circuit_potential/dchs_ocp.py index 3c86d54751..bbe2d483a4 100644 --- a/pybamm/models/submodels/interface/open_circuit_potential/dchs_ocp.py +++ b/pybamm/models/submodels/interface/open_circuit_potential/dchs_ocp.py @@ -42,8 +42,8 @@ def get_coupled_variables(self, variables): ): sto_surf = sto_surf.orphans[0] T = T.orphans[0] - T = pybamm.PrimaryBroadcast(T, [f"{domain} particle size"]) - h = pybamm.PrimaryBroadcast(h, [f"{domain} particle size"]) + T = pybamm.PrimaryBroadcast(T, [f"{domain} {phase_name}particle size"]) + h = pybamm.PrimaryBroadcast(h, [f"{domain} {phase_name}particle size"]) else: sto_surf = variables[ f"{Domain} {phase_name}particle surface stoichiometry" @@ -103,6 +103,8 @@ def get_coupled_variables(self, variables): # must be DFN with PSD model elif f"{domain} electrode" in sto_surf.domains["secondary"]: ocp_surf = ocp_surf_eq + H * h + elif f"{domain} {phase_name}particle size" in sto_surf.domains["primary"]: + ocp_surf = ocp_surf_eq + H * h # must not be a psd else: ocp_surf = ocp_surf_eq + H * h From 00a2e8eb5bfbebf07a37c78a666af42c1ad61275 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 30 Apr 2024 23:52:07 +0000 Subject: [PATCH 32/43] style: pre-commit fixes --- .../submodels/interface/open_circuit_potential/dchs_ocp.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pybamm/models/submodels/interface/open_circuit_potential/dchs_ocp.py b/pybamm/models/submodels/interface/open_circuit_potential/dchs_ocp.py index bbe2d483a4..b992cd276c 100644 --- a/pybamm/models/submodels/interface/open_circuit_potential/dchs_ocp.py +++ b/pybamm/models/submodels/interface/open_circuit_potential/dchs_ocp.py @@ -103,7 +103,9 @@ def get_coupled_variables(self, variables): # must be DFN with PSD model elif f"{domain} electrode" in sto_surf.domains["secondary"]: ocp_surf = ocp_surf_eq + H * h - elif f"{domain} {phase_name}particle size" in sto_surf.domains["primary"]: + elif ( + f"{domain} {phase_name}particle size" in sto_surf.domains["primary"] + ): ocp_surf = ocp_surf_eq + H * h # must not be a psd else: From 8ad82141c6ba02b4e66c93228b2849550f6565f8 Mon Sep 17 00:00:00 2001 From: Tanner Leo Date: Thu, 2 May 2024 10:43:36 -0700 Subject: [PATCH 33/43] update notebook name --- docs/source/examples/index.rst | 2 +- ...{DCHS.ipynb => differential-capacity-hysteresis-state.ipynb} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename docs/source/examples/notebooks/models/{DCHS.ipynb => differential-capacity-hysteresis-state.ipynb} (100%) diff --git a/docs/source/examples/index.rst b/docs/source/examples/index.rst index df74a922cb..a4340adf8d 100644 --- a/docs/source/examples/index.rst +++ b/docs/source/examples/index.rst @@ -50,7 +50,7 @@ The notebooks are organised into subfolders, and can be viewed in the galleries notebooks/models/compare-particle-diffusion-models.ipynb notebooks/models/composite_particle.ipynb notebooks/models/coupled-degradation.ipynb - notebooks/models/DCHS.ipynb + notebooks/models/differential-capacity-hysteresis-state.ipynb notebooks/models/DFN-with-particle-size-distributions.ipynb notebooks/models/DFN.ipynb notebooks/models/electrode-state-of-health.ipynb diff --git a/docs/source/examples/notebooks/models/DCHS.ipynb b/docs/source/examples/notebooks/models/differential-capacity-hysteresis-state.ipynb similarity index 100% rename from docs/source/examples/notebooks/models/DCHS.ipynb rename to docs/source/examples/notebooks/models/differential-capacity-hysteresis-state.ipynb From 2f947d9c838ebac2f3c8f88bb3d6eae5693547c7 Mon Sep 17 00:00:00 2001 From: Tanner Leo Date: Thu, 2 May 2024 10:51:29 -0700 Subject: [PATCH 34/43] rename to Wycisk from DCHS --- pybamm/models/full_battery_models/base_battery_model.py | 4 ++-- .../full_battery_models/lithium_ion/base_lithium_ion_model.py | 4 ++-- .../submodels/interface/open_circuit_potential/__init__.py | 2 +- .../open_circuit_potential/{dchs_ocp.py => wycisk_ocp.py} | 2 +- .../test_full_battery_models/test_lithium_ion/test_mpm.py | 2 +- .../test_full_battery_models/test_base_battery_model.py | 2 +- .../test_lithium_ion/base_lithium_ion_tests.py | 2 +- .../test_full_battery_models/test_lithium_ion/test_dfn.py | 4 ++-- .../test_full_battery_models/test_lithium_ion/test_mpm.py | 2 +- 9 files changed, 12 insertions(+), 12 deletions(-) rename pybamm/models/submodels/interface/open_circuit_potential/{dchs_ocp.py => wycisk_ocp.py} (99%) diff --git a/pybamm/models/full_battery_models/base_battery_model.py b/pybamm/models/full_battery_models/base_battery_model.py index 5840df2844..66a83f9e4d 100644 --- a/pybamm/models/full_battery_models/base_battery_model.py +++ b/pybamm/models/full_battery_models/base_battery_model.py @@ -102,7 +102,7 @@ class BatteryModelOptions(pybamm.FuzzyDict): reactions. * "open-circuit potential" : str Sets the model for the open circuit potential. Can be "single" - (default), "current sigmoid", "DCHS", or "MSMR". If "MSMR" then the "particle" + (default), "current sigmoid", "Wycisk", or "MSMR". If "MSMR" then the "particle" option must also be "MSMR". A 2-tuple can be provided for different behaviour in negative and positive electrodes. * "operating mode" : str @@ -263,7 +263,7 @@ def __init__(self, extra_options): "stress and reaction-driven", ], "number of MSMR reactions": ["none"], - "open-circuit potential": ["single", "current sigmoid", "MSMR", "DCHS"], + "open-circuit potential": ["single", "current sigmoid", "MSMR", "Wycisk"], "operating mode": [ "current", "voltage", 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 7000869e16..55e62897bf 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 @@ -248,9 +248,9 @@ def set_open_circuit_potential_submodel(self): ocp_model = ocp_submodels.SingleOpenCircuitPotential elif ocp_option == "current sigmoid": ocp_model = ocp_submodels.CurrentSigmoidOpenCircuitPotential - elif ocp_option == "DCHS": + elif ocp_option == "Wycisk": pybamm.citations.register("Wycisk2022") - ocp_model = ocp_submodels.DCHSOpenCircuitPotential + ocp_model = ocp_submodels.WyciskOpenCircuitPotential elif ocp_option == "MSMR": ocp_model = ocp_submodels.MSMROpenCircuitPotential self.submodels[f"{domain} {phase} open-circuit potential"] = ocp_model( diff --git a/pybamm/models/submodels/interface/open_circuit_potential/__init__.py b/pybamm/models/submodels/interface/open_circuit_potential/__init__.py index c52c735aac..618a130f65 100644 --- a/pybamm/models/submodels/interface/open_circuit_potential/__init__.py +++ b/pybamm/models/submodels/interface/open_circuit_potential/__init__.py @@ -2,4 +2,4 @@ from .single_ocp import SingleOpenCircuitPotential from .current_sigmoid_ocp import CurrentSigmoidOpenCircuitPotential from .msmr_ocp import MSMROpenCircuitPotential -from .dchs_ocp import DCHSOpenCircuitPotential +from .wycisk_ocp import WyciskOpenCircuitPotential diff --git a/pybamm/models/submodels/interface/open_circuit_potential/dchs_ocp.py b/pybamm/models/submodels/interface/open_circuit_potential/wycisk_ocp.py similarity index 99% rename from pybamm/models/submodels/interface/open_circuit_potential/dchs_ocp.py rename to pybamm/models/submodels/interface/open_circuit_potential/wycisk_ocp.py index b992cd276c..21286c681e 100644 --- a/pybamm/models/submodels/interface/open_circuit_potential/dchs_ocp.py +++ b/pybamm/models/submodels/interface/open_circuit_potential/wycisk_ocp.py @@ -5,7 +5,7 @@ from . import BaseOpenCircuitPotential -class DCHSOpenCircuitPotential(BaseOpenCircuitPotential): +class WyciskOpenCircuitPotential(BaseOpenCircuitPotential): def get_fundamental_variables(self): domain, Domain = self.domain_Domain phase_name = self.phase_name diff --git a/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_mpm.py b/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_mpm.py index d52785a2f3..f895215954 100644 --- a/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_mpm.py +++ b/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_mpm.py @@ -69,7 +69,7 @@ def test_current_sigmoid_ocp(self): modeltest.test_all(skip_output_tests=True) def test_dchs_ocp(self): - options = {"open-circuit potential": ("DCHS", "single")} + options = {"open-circuit potential": ("Wycisk", "single")} model = pybamm.lithium_ion.MPM(options) parameter_values = pybamm.ParameterValues("Chen2020") parameter_values = pybamm.get_size_distribution_parameters(parameter_values) 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 75047db928..5ff5027c1a 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 @@ -33,7 +33,7 @@ 'lithium plating porosity change': 'false' (possible: ['false', 'true']) 'loss of active material': 'stress-driven' (possible: ['none', 'stress-driven', 'reaction-driven', 'current-driven', 'stress and reaction-driven']) 'number of MSMR reactions': 'none' (possible: ['none']) -'open-circuit potential': 'single' (possible: ['single', 'current sigmoid', 'MSMR', 'DCHS']) +'open-circuit potential': 'single' (possible: ['single', 'current sigmoid', 'MSMR', 'Wycisk']) 'operating mode': 'current' (possible: ['current', 'voltage', 'power', 'differential power', 'explicit power', 'resistance', 'differential resistance', 'explicit resistance', 'CCCV']) 'particle': 'Fickian diffusion' (possible: ['Fickian diffusion', 'fast diffusion', 'uniform profile', 'quadratic profile', 'quartic profile', 'MSMR']) 'particle mechanics': 'swelling only' (possible: ['none', 'swelling only', 'swelling and cracking']) diff --git a/tests/unit/test_models/test_full_battery_models/test_lithium_ion/base_lithium_ion_tests.py b/tests/unit/test_models/test_full_battery_models/test_lithium_ion/base_lithium_ion_tests.py index 9867a4f122..c51d2ae12a 100644 --- a/tests/unit/test_models/test_full_battery_models/test_lithium_ion/base_lithium_ion_tests.py +++ b/tests/unit/test_models/test_full_battery_models/test_lithium_ion/base_lithium_ion_tests.py @@ -407,7 +407,7 @@ def test_well_posed_current_sigmoid_ocp(self): self.check_well_posedness(options) def test_well_posed_dchs_ocp(self): - options = {"open-circuit potential": "DCHS"} + options = {"open-circuit potential": "Wycisk"} self.check_well_posedness(options) def test_well_posed_msmr(self): diff --git a/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_dfn.py b/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_dfn.py index 76c78aab8a..b17ee35f3f 100644 --- a/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_dfn.py +++ b/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_dfn.py @@ -37,14 +37,14 @@ def test_well_posed_current_sigmoid_ocp_with_psd(self): def test_well_posed_dchs_ocp_with_psd(self): options = { - "open-circuit potential": "DCHS", + "open-circuit potential": "Wycisk", "particle size": "distribution", } self.check_well_posedness(options) def test_well_posed_dchs_ocp_with_composite(self): options = { - "open-circuit potential": (("DCHS", "single"), "single"), + "open-circuit potential": (("Wycisk", "single"), "single"), "particle phases": ("2", "1"), } self.check_well_posedness(options) diff --git a/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_mpm.py b/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_mpm.py index d74a7cd934..4e37a12c30 100644 --- a/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_mpm.py +++ b/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_mpm.py @@ -118,7 +118,7 @@ def test_msmr(self): def test_dchs_ocp(self): options = { - "open-circuit potential": "DCHS", + "open-circuit potential": "Wycisk", } model = pybamm.lithium_ion.MPM(options) model.check_well_posedness() From 9566f50982b79b4b5c969e0a1c495f32cd9b35e3 Mon Sep 17 00:00:00 2001 From: Tanner Leo Date: Thu, 2 May 2024 11:13:30 -0700 Subject: [PATCH 35/43] update parameters required & names --- ...fferential-capacity-hysteresis-state.ipynb | 14 +++++++------- .../open_circuit_potential/wycisk_ocp.py | 6 +++--- pybamm/parameters/lithium_ion_parameters.py | 19 ++++++++++++++----- .../test_lithium_ion/test_mpm.py | 13 ++++++++----- .../base_lithium_ion_tests.py | 2 +- .../test_lithium_ion/test_dfn.py | 4 ++-- .../test_lithium_ion/test_mpm.py | 2 +- 7 files changed, 36 insertions(+), 24 deletions(-) diff --git a/docs/source/examples/notebooks/models/differential-capacity-hysteresis-state.ipynb b/docs/source/examples/notebooks/models/differential-capacity-hysteresis-state.ipynb index 02b3007f95..fec3567390 100644 --- a/docs/source/examples/notebooks/models/differential-capacity-hysteresis-state.ipynb +++ b/docs/source/examples/notebooks/models/differential-capacity-hysteresis-state.ipynb @@ -76,7 +76,7 @@ "source": [ "model_DCHS = pybamm.lithium_ion.DFN(\n", " {\n", - " \"open-circuit potential\": ((\"single\", \"DCHS\"), \"single\"),\n", + " \"open-circuit potential\": ((\"single\", \"Wycisk\"), \"single\"),\n", " \"particle phases\": (\"2\", \"1\"),\n", " }\n", ")\n", @@ -126,7 +126,7 @@ "parameters_DCHS.update(\n", " {\n", " \"Secondary: Negative electrode OCP [V]\": ocp_avg,\n", - " \"Secondary: Negative electrode OCP hysteresis [V]\": hysteresis,\n", + " # \"Secondary: Negative electrode OCP hysteresis [V]\": hysteresis,\n", " },\n", " check_already_exists=False,\n", ")" @@ -245,12 +245,12 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "2dc1c68398924dafad346326317839db", + "model_id": "2344463a0a7f4455bf5a4656a9dddbfa", "version_major": 2, "version_minor": 0 }, "text/plain": [ - "interactive(children=(FloatSlider(value=0.0, description='t', max=3.149265739087976, step=0.03149265739087976)…" + "interactive(children=(FloatSlider(value=0.0, description='t', max=3.1492654802910014, step=0.03149265480291001…" ] }, "metadata": {}, @@ -271,18 +271,18 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "0de9e59cc56d475cbb49b772442f3ed8", + "model_id": "b2ae424fa5524d55b82350d1ec5aa40f", "version_major": 2, "version_minor": 0 }, "text/plain": [ - "interactive(children=(FloatSlider(value=0.0, description='t', max=3.149265739087976, step=0.03149265739087976)…" + "interactive(children=(FloatSlider(value=0.0, description='t', max=3.1492654802910014, step=0.03149265480291001…" ] }, "metadata": {}, diff --git a/pybamm/models/submodels/interface/open_circuit_potential/wycisk_ocp.py b/pybamm/models/submodels/interface/open_circuit_potential/wycisk_ocp.py index 21286c681e..e032a40015 100644 --- a/pybamm/models/submodels/interface/open_circuit_potential/wycisk_ocp.py +++ b/pybamm/models/submodels/interface/open_circuit_potential/wycisk_ocp.py @@ -77,7 +77,7 @@ def get_coupled_variables(self, variables): ocp_bulk_eq ) - H = self.phase_param.H(sto_surf) + H = self.phase_param.hysteresis(sto_surf) variables[f"{Domain} electrode {phase_name}OCP hysteresis [V]"] = H dU = self.phase_param.U(sto_surf, T_bulk).diff(sto_surf) @@ -138,8 +138,8 @@ def set_rhs(self, variables): f"{Domain} electrode {phase_name}differential capacity [A.s.V-1]" ] dQdU = dQdU.orphans[0] - K = self.phase_param.K - K_x = self.phase_param.K_x + K = self.phase_param.hysteresis_decay + K_x = self.phase_param.hysteresis_switch h = variables[f"{Domain} electrode {phase_name}hysteresis state"] dhdt = ( diff --git a/pybamm/parameters/lithium_ion_parameters.py b/pybamm/parameters/lithium_ion_parameters.py index 588bbe09b7..ad3e37887e 100644 --- a/pybamm/parameters/lithium_ion_parameters.py +++ b/pybamm/parameters/lithium_ion_parameters.py @@ -536,8 +536,10 @@ def _set_parameters(self): self.epsilon_s * pybamm.r_average(self.c_init) ) # if self.options['open-circuit potential'] == 'Plett': - self.K = pybamm.Parameter(f"{pref}{Domain} particle hysteresis decay rate") - self.K_x = pybamm.Parameter( + self.hysteresis_decay = pybamm.Parameter( + f"{pref}{Domain} particle hysteresis decay rate" + ) + self.hysteresis_switch = pybamm.Parameter( f"{pref}{Domain} particle hysteresis switching factor" ) self.h_init = pybamm.Scalar(0) @@ -636,15 +638,22 @@ def U(self, sto, T, lithiation=None): out.print_name = r"U_\mathrm{p}(c^\mathrm{surf}_\mathrm{s,p}, T)" return out - def H(self, sto): + def hysteresis(self, sto): """Dimensional hysteresis [V]""" Domain = self.domain.capitalize() # tol = pybamm.settings.tolerances["U__c_s"] # sto = pybamm.maximum(pybamm.minimum(sto,1-tol),tol) inputs = {f"{self.phase_prefactor}{Domain} particle stoichiometry": sto} - h_ref = pybamm.FunctionParameter( - f"{self.phase_prefactor}{Domain} electrode OCP hysteresis [V]", inputs + lith_ref = pybamm.FunctionParameter( + f"{self.phase_prefactor}{Domain} electrode lithiation OCP [V]", inputs + ) + delith_ref = pybamm.FunctionParameter( + f"{self.phase_prefactor}{Domain} electrode delithiation OCP [V]", inputs ) + h_ref = abs(delith_ref - lith_ref) / 2 + # h_ref = pybamm.FunctionParameter( + # f"{self.phase_prefactor}{Domain} electrode OCP hysteresis [V]", inputs + # ) return h_ref def Q(self, sto): diff --git a/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_mpm.py b/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_mpm.py index f895215954..82d228badb 100644 --- a/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_mpm.py +++ b/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_mpm.py @@ -68,19 +68,22 @@ def test_current_sigmoid_ocp(self): modeltest = tests.StandardModelTest(model, parameter_values=parameter_values) modeltest.test_all(skip_output_tests=True) - def test_dchs_ocp(self): + def test_wycisk_ocp(self): options = {"open-circuit potential": ("Wycisk", "single")} model = pybamm.lithium_ion.MPM(options) parameter_values = pybamm.ParameterValues("Chen2020") parameter_values = pybamm.get_size_distribution_parameters(parameter_values) parameter_values.update( { - "Negative electrode OCP [V]" "": parameter_values[ - "Negative electrode OCP [V]" - ], + "Negative electrode lithiation OCP [V]" + "": lambda sto: parameter_values["Negative electrode OCP [V]"](sto) + - 0.1, + "Negative electrode delithiation OCP [V]" + "": lambda sto: parameter_values["Negative electrode OCP [V]"](sto) + + 0.1, "Negative particle hysteresis decay rate": 1, "Negative particle hysteresis switching factor": 1, - "Negative electrode OCP hysteresis [V]": lambda sto: 1, + # "Negative electrode OCP hysteresis [V]": lambda sto: 1, }, check_already_exists=False, ) diff --git a/tests/unit/test_models/test_full_battery_models/test_lithium_ion/base_lithium_ion_tests.py b/tests/unit/test_models/test_full_battery_models/test_lithium_ion/base_lithium_ion_tests.py index c51d2ae12a..4302681dc2 100644 --- a/tests/unit/test_models/test_full_battery_models/test_lithium_ion/base_lithium_ion_tests.py +++ b/tests/unit/test_models/test_full_battery_models/test_lithium_ion/base_lithium_ion_tests.py @@ -406,7 +406,7 @@ def test_well_posed_current_sigmoid_ocp(self): options = {"open-circuit potential": "current sigmoid"} self.check_well_posedness(options) - def test_well_posed_dchs_ocp(self): + def test_well_posed_wycisk_ocp(self): options = {"open-circuit potential": "Wycisk"} self.check_well_posedness(options) diff --git a/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_dfn.py b/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_dfn.py index b17ee35f3f..20fc69e541 100644 --- a/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_dfn.py +++ b/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_dfn.py @@ -35,14 +35,14 @@ def test_well_posed_current_sigmoid_ocp_with_psd(self): } self.check_well_posedness(options) - def test_well_posed_dchs_ocp_with_psd(self): + def test_well_posed_wycisk_ocp_with_psd(self): options = { "open-circuit potential": "Wycisk", "particle size": "distribution", } self.check_well_posedness(options) - def test_well_posed_dchs_ocp_with_composite(self): + def test_well_posed_wycisk_ocp_with_composite(self): options = { "open-circuit potential": (("Wycisk", "single"), "single"), "particle phases": ("2", "1"), diff --git a/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_mpm.py b/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_mpm.py index 4e37a12c30..389aa55849 100644 --- a/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_mpm.py +++ b/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_mpm.py @@ -116,7 +116,7 @@ def test_msmr(self): model = pybamm.lithium_ion.MPM(options) model.check_well_posedness() - def test_dchs_ocp(self): + def test_wycisk_ocp(self): options = { "open-circuit potential": "Wycisk", } From eb2fe95c11e269754eae73c544e404491c125368 Mon Sep 17 00:00:00 2001 From: Tanner Leo Date: Thu, 2 May 2024 11:45:23 -0700 Subject: [PATCH 36/43] change if statement for code cov --- .../interface/open_circuit_potential/wycisk_ocp.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pybamm/models/submodels/interface/open_circuit_potential/wycisk_ocp.py b/pybamm/models/submodels/interface/open_circuit_potential/wycisk_ocp.py index e032a40015..7f997a7627 100644 --- a/pybamm/models/submodels/interface/open_circuit_potential/wycisk_ocp.py +++ b/pybamm/models/submodels/interface/open_circuit_potential/wycisk_ocp.py @@ -101,12 +101,12 @@ def get_coupled_variables(self, variables): if "current collector" in sto_surf.domains["secondary"]: ocp_surf = ocp_surf_eq + H_x_av * h_x_av # must be DFN with PSD model - elif f"{domain} electrode" in sto_surf.domains["secondary"]: + elif ( + f"{domain} electrode" in sto_surf.domains["secondary"] + or f"{domain} {phase_name}particle size" + in sto_surf.domains["primary"] + ): ocp_surf = ocp_surf_eq + H * h - elif ( - f"{domain} {phase_name}particle size" in sto_surf.domains["primary"] - ): - ocp_surf = ocp_surf_eq + H * h # must not be a psd else: ocp_surf = ocp_surf_eq + H * h From 647be7b38437fa6ed8362eb8981b3a8d58e2e9be Mon Sep 17 00:00:00 2001 From: Tanner Leo Date: Fri, 3 May 2024 09:49:23 -0700 Subject: [PATCH 37/43] add docs --- .../interface/open_circuit_potential/wycisk_ocp.rst | 5 +++++ .../submodels/interface/open_circuit_potential/wycisk_ocp.py | 5 +++++ 2 files changed, 10 insertions(+) create mode 100644 docs/source/api/models/submodels/interface/open_circuit_potential/wycisk_ocp.rst diff --git a/docs/source/api/models/submodels/interface/open_circuit_potential/wycisk_ocp.rst b/docs/source/api/models/submodels/interface/open_circuit_potential/wycisk_ocp.rst new file mode 100644 index 0000000000..191869c882 --- /dev/null +++ b/docs/source/api/models/submodels/interface/open_circuit_potential/wycisk_ocp.rst @@ -0,0 +1,5 @@ +Wycisk Open Circuit Potential +============================= + +.. autoclass:: pybamm.open_circuit_potential.WyciskOpenCircuitPotential + :members: \ No newline at end of file diff --git a/pybamm/models/submodels/interface/open_circuit_potential/wycisk_ocp.py b/pybamm/models/submodels/interface/open_circuit_potential/wycisk_ocp.py index 7f997a7627..f218b1c63b 100644 --- a/pybamm/models/submodels/interface/open_circuit_potential/wycisk_ocp.py +++ b/pybamm/models/submodels/interface/open_circuit_potential/wycisk_ocp.py @@ -6,6 +6,11 @@ class WyciskOpenCircuitPotential(BaseOpenCircuitPotential): + """ + Class for open-circuit potential with hysteresis based on the approach outlined by Wycisk :footcite:t:'Wycisk2022'. + This approach employs a differential capacity hysteresis state variable. The decay and switching of the hysteresis state + is tunable via two additional parameters. The hysteresis state is updated based on the current and the differential capacity. + """ def get_fundamental_variables(self): domain, Domain = self.domain_Domain phase_name = self.phase_name From ec466f0405dec0d5697fd9eff68de79d3e835aee Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 3 May 2024 16:50:07 +0000 Subject: [PATCH 38/43] style: pre-commit fixes --- .../submodels/interface/open_circuit_potential/wycisk_ocp.rst | 2 +- .../submodels/interface/open_circuit_potential/wycisk_ocp.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/source/api/models/submodels/interface/open_circuit_potential/wycisk_ocp.rst b/docs/source/api/models/submodels/interface/open_circuit_potential/wycisk_ocp.rst index 191869c882..6952a2ee44 100644 --- a/docs/source/api/models/submodels/interface/open_circuit_potential/wycisk_ocp.rst +++ b/docs/source/api/models/submodels/interface/open_circuit_potential/wycisk_ocp.rst @@ -2,4 +2,4 @@ Wycisk Open Circuit Potential ============================= .. autoclass:: pybamm.open_circuit_potential.WyciskOpenCircuitPotential - :members: \ No newline at end of file + :members: diff --git a/pybamm/models/submodels/interface/open_circuit_potential/wycisk_ocp.py b/pybamm/models/submodels/interface/open_circuit_potential/wycisk_ocp.py index f218b1c63b..43b13e6d3b 100644 --- a/pybamm/models/submodels/interface/open_circuit_potential/wycisk_ocp.py +++ b/pybamm/models/submodels/interface/open_circuit_potential/wycisk_ocp.py @@ -7,10 +7,11 @@ class WyciskOpenCircuitPotential(BaseOpenCircuitPotential): """ - Class for open-circuit potential with hysteresis based on the approach outlined by Wycisk :footcite:t:'Wycisk2022'. + Class for open-circuit potential with hysteresis based on the approach outlined by Wycisk :footcite:t:'Wycisk2022'. This approach employs a differential capacity hysteresis state variable. The decay and switching of the hysteresis state is tunable via two additional parameters. The hysteresis state is updated based on the current and the differential capacity. """ + def get_fundamental_variables(self): domain, Domain = self.domain_Domain phase_name = self.phase_name From e72f79937b8d6479daf632061cfe9c4037b94a21 Mon Sep 17 00:00:00 2001 From: Tanner Leo Date: Fri, 3 May 2024 10:30:56 -0700 Subject: [PATCH 39/43] update toctree --- .../models/submodels/interface/open_circuit_potential/index.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/source/api/models/submodels/interface/open_circuit_potential/index.rst b/docs/source/api/models/submodels/interface/open_circuit_potential/index.rst index fc664adf2b..3a20bccb17 100644 --- a/docs/source/api/models/submodels/interface/open_circuit_potential/index.rst +++ b/docs/source/api/models/submodels/interface/open_circuit_potential/index.rst @@ -7,3 +7,4 @@ Open-circuit potential models current_sigmoid_ocp single_ocp msmr_ocp + wycisk_ocp From f02551e01a41af14c0b8fdfda8ba0479671903ea Mon Sep 17 00:00:00 2001 From: Tanner Leo Date: Sun, 5 May 2024 14:48:21 -0700 Subject: [PATCH 40/43] add to changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 118a18197a..1db67a50df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ - Renamed "electrode diffusivity" to "particle diffusivity" as a non-breaking change with a deprecation warning ([#3624](https://github.com/pybamm-team/PyBaMM/pull/3624)) - Add support for BPX version 0.4.0 which allows for blended electrodes and user-defined parameters in BPX([#3414](https://github.com/pybamm-team/PyBaMM/pull/3414)) - Added `by_submodel` feature in `print_parameter_info` method to allow users to print parameters and types of submodels in a tabular and readable format ([#3628](https://github.com/pybamm-team/PyBaMM/pull/3628)) +- Added `WyciskOpenCircuitPotential` for differential capacity hysteresis state open-circuit potential submodel ([#3593](https://github.com/pybamm-team/PyBaMM/pull/3593)) ## Bug Fixes From 31b711578679921e3ee0c3e4883eb3aabcc467f0 Mon Sep 17 00:00:00 2001 From: Tanner Leo Date: Tue, 7 May 2024 10:49:40 -0700 Subject: [PATCH 41/43] move functions inside submodel --- ...fferential-capacity-hysteresis-state.ipynb | 72 ++----------------- .../open_circuit_potential/wycisk_ocp.py | 41 ++++++++++- pybamm/parameters/lithium_ion_parameters.py | 27 ------- 3 files changed, 46 insertions(+), 94 deletions(-) diff --git a/docs/source/examples/notebooks/models/differential-capacity-hysteresis-state.ipynb b/docs/source/examples/notebooks/models/differential-capacity-hysteresis-state.ipynb index fec3567390..f3bda4a98c 100644 --- a/docs/source/examples/notebooks/models/differential-capacity-hysteresis-state.ipynb +++ b/docs/source/examples/notebooks/models/differential-capacity-hysteresis-state.ipynb @@ -22,8 +22,7 @@ ], "source": [ "%pip install \"pybamm[plot,cite]\" -q # install PyBaMM if it is not installed\n", - "import pybamm\n", - "import matplotlib.pyplot as plt" + "import pybamm" ] }, { @@ -107,81 +106,24 @@ "\n", "\n", "# get the lithiation and delithiation functions\n", - "\n", "lithiation_ocp = parameters_DCHS[\"Secondary: Negative electrode lithiation OCP [V]\"]\n", "delithiation_ocp = parameters_DCHS[\"Secondary: Negative electrode delithiation OCP [V]\"]\n", "\n", "\n", - "# define the new OCP function\n", + "# define an additional OCP function\n", "def ocp_avg(sto):\n", " return (lithiation_ocp(sto) + delithiation_ocp(sto)) / 2\n", "\n", "\n", - "# define hysteresis function\n", - "def hysteresis(sto):\n", - " return (lithiation_ocp(sto) - delithiation_ocp(sto)) / -2\n", - "\n", - "\n", "# add additional parameters\n", "parameters_DCHS.update(\n", " {\n", " \"Secondary: Negative electrode OCP [V]\": ocp_avg,\n", - " # \"Secondary: Negative electrode OCP hysteresis [V]\": hysteresis,\n", " },\n", " check_already_exists=False,\n", ")" ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "To visualize what our new ocp_avg and hysteresis state function looks like, we will plot it against stoichiometry" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAArIAAAMWCAYAAAANg2XMAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAA9hAAAPYQGoP6dpAAD7SElEQVR4nOzdd3hUZdrH8e/MpPfeeyXU0HsTEJAilhWRFbCvZe26dnDX8q4VFQtW1LWgKGKh14SA9FBCIAnpvfeemfePIQMjARJSZpLcn+uaa5I5z5xzBwP+8uQ+z6PQaDQahBBCCCGE6GaUhi5ACCGEEEKIKyFBVgghhBBCdEsSZIUQQgghRLckQVYIIYQQQnRLEmSFEEIIIUS3JEFWCCGEEEJ0SxJkhRBCCCFEtyRBVgghhBBCdEsmhi7AGKnVarKzs7G1tUWhUBi6HCGEEEKIXkOj0VBRUYGXlxdK5aXnXCXItiA7OxtfX19DlyGEEEII0WtlZGTg4+NzyTESZFtga2sLaP8A7ezsDFyNEEIIIUTvUV5ejq+vry6PXYoE2RY0txPY2dlJkBVCCCGEMIDWtHfKzV5CCCGEEKJbkiArhBBCCCG6JQmyQgghhBCiW5IeWSGEEKKXampqoqGhwdBliF7G1NQUlUrVIeeSICuEEEL0MhqNhtzcXEpLSw1diuilHBwc8PDwaPd6/RJkhRBCiF6mOcS6ublhZWUlm/+ILqPRaKiuriY/Px8AT0/Pdp3P6INsVFQUr7/+OocOHSInJ4e1a9cyb968S75n586dPProo8TFxeHr68tzzz3HkiVLuqReIYQQwpg1NTXpQqyzs7OhyxG9kKWlJQD5+fm4ubm1q83A6G/2qqqqYtCgQbz//vutGp+SksKsWbOYPHkysbGxPPzww9x5551s2rSpkysVQgghjF9zT6yVlZWBKxG9WfP3X3t7tI1+RnbmzJnMnDmz1eM/+ugjAgMDefPNNwGIiIhg9+7dvP3220yfPr2zyhRCCCG6FWknEIbUUd9/Rj8j21Z79+5l6tSpeq9Nnz6dvXv3GqgiIYQQQgjRGXpckM3NzcXd3V3vNXd3d8rLy6mpqWnxPXV1dZSXl+s9hBBCCGF8MjIyuP322/Hy8sLMzAx/f38eeughioqKLhiblJTEbbfdho+PD+bm5gQGBrJgwQIOHjyoG6NQKHQPe3t7xo4dy/bt27vySxLt0OOC7JV49dVXsbe31z18fX279Pr1TfVkV2Z36TWFEEKI7iY5OZlhw4aRmJjId999R1JSEh999BHbtm1j9OjRFBcX68YePHiQoUOHkpCQwMqVKzl58iRr166lT58+PPbYY3rn/eKLL8jJySEmJgYXFxdmz55NcnJyV395lyTr/basxwVZDw8P8vLy9F7Ly8vDzs5Od5fcXz399NOUlZXpHhkZGV1RKgAHcg8w/afp/CvqX112TSGEEKI7uv/++zEzM2Pz5s1MnDgRPz8/Zs6cydatW8nKyuLZZ58FtEs8LVmyhNDQUKKjo5k1axbBwcFERkaydOlS1q1bp3fe5jVN+/fvz4cffkhNTQ1btmxpsYaioiIWLFiAt7c3VlZWDBgwgO+++053/OOPP8bLywu1Wq33vmuvvZbbb79d9/m6desYMmQIFhYWBAUF8eKLL9LY2Kg7rlAo+PDDD5k7dy7W1ta8/PLLNDU1cccddxAYGIilpSXh4eG88847etdpbGzkwQcfxMHBAWdnZ/71r3+xePFivRWf1Go1r776qu48gwYNYs2aNW37j2EkelyQHT16NNu2bdN7bcuWLYwePfqi7zE3N8fOzk7v0VUC7AIoqysjtiCW2PzYLruuEEII0Z0UFxezadMm7rvvvgsmpjw8PFi4cCGrV69Go9EQGxtLXFwcjz32GErlhVHHwcHhotdpPnd9fX2Lx2traxk6dCh//PEHJ06c4O677+bWW29l//79APztb3+jqKiIHTt26NW+ceNGFi5cCEB0dDSLFi3ioYce4uTJk6xcuZJVq1bx8ssv611r2bJlXHfddRw/fpzbb78dtVqNj48PP/74IydPnuSFF17gmWee4YcfftC957///S/ffPMNX3zxBTExMZSXl/PLL7/onffVV1/lq6++4qOPPiIuLo5HHnmEv//97+zateuify5GS2PkKioqNEeOHNEcOXJEA2jeeustzZEjRzRpaWkajUajeeqppzS33nqrbnxycrLGyspK88QTT2ji4+M177//vkalUmk2btzY6muWlZVpAE1ZWVmHfz0teX7385r+q/prHtr+UJdcTwghRO9VU1OjOXnypKampkb3mlqt1lTVNRjkoVarW1X3n3/+qQE0a9eubfH4W2+9pQE0eXl5mtWrV2sAzeHDhy973vPPWVVVpbnvvvs0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cDYlV+py6kTyILthwwaEhYVh/vz5iIqKQo8ePRASEoKMjIwa2x8+fBjjxo3DlClTEB0djdDQUISGhuLMmTPV2m7evBlHjhyBm5tbY78NIiIiIpNkppAj0NsegOltVyt5kF28eDGmTp2KyZMno0uXLli+fDksLS2xcuXKGtt/9tlnGDFiBGbNmgVfX1+8++676N27N5YuXVqlXXJyMl544QWsXbsW5ubmTfFWiIiIiEzSgJvDC0xtwpekQbasrAyRkZEIDg42nJPL5QgODkZERESN10RERFRpDwAhISFV2ut0OowfPx6zZs1C165d71hHaWkp8vLyqhxERERELUVlkD1+JRulFVqJq6k9SYNsVlYWtFotnJ2dq5x3dnZGWlpajdekpaXdsf1HH30EMzMzvPjii7WqY8GCBdBoNIbDw8Ojju+EiIiIyHR1dLKGo40KJeU6RF3NkbqcWpN8aEFDi4yMxGeffYbVq1dDJpPV6po5c+YgNzfXcCQlJTVylURERETGQyaToX97/TJcpjS8QNIg6+DgAIVCgfT09Crn09PT4eLiUuM1Li4ut23/119/ISMjA23btoWZmRnMzMxw9epV/Pe//4WXl1eN91SpVLC1ta1yEBEREbUkldvVHr5sOhO+JA2ySqUS/v7+CA8PN5zT6XQIDw9HUFBQjdcEBQVVaQ8Au3fvNrQfP348Tp06hZiYGMPh5uaGWbNmYdeuXY33ZoiIiIhMWN92+pULTl/LRUm5aYyTNZO6gLCwMEycOBF9+vRB3759sWTJEhQWFmLy5MkAgAkTJsDd3R0LFiwAALz00ksYPHgwFi1ahJEjR2L9+vU4ceIEvv76awBA69at0bp16yqvYW5uDhcXF3Tu3Llp3xwRERGRifBsbQkHayWyCspwOjkXAV72Upd0R5IH2bFjxyIzMxPz5s1DWloaevbsiZ07dxomdCUmJkIu/7vjuH///li3bh3mzp2L119/HR07dsSWLVvQrVs3qd4CERERkcmTyWTw92yFXWfTceLKDZMIsjIhhGntRdYE8vLyoNFokJuby/GyRERE1GKsOBCP93fEItjXCd9MDJCkhrrksGa3agERERER1Y+/VysAQOTVGzCFvk4GWSIiIiICAHRz00BlJseNonJcziyUupw7YpAlIiIiIgCA0kyOHh52AIDIq9nSFlMLDLJEREREZNDHUz+84MSVGxJXcmcMskRERERk0Ocf42SNHYMsERERERn0bqsPsvFZhbheUCpxNbfHIEtEREREBnaWSnR0sgZg/L2yDLJEREREVIWpDC9gkCUiIiKiKvw99bt6nWCQJSIiIiJTUrlywelruSgp10pcza0xyBIRERFRFZ6tLeFgrUSZVoczyblSl3NLDLJEREREVIVMJoN/5XqyRjy8gEGWiIiIiKrpUzlO1og3RmCQJSIiIqJq/G+uXBCVeANCCImrqRmDLBERERFV081NA5WZHNmFZYjPKpS6nBoxyBIRERFRNUozOXp42AEAIo10eAGDLBERERHVqI9hwle2xJXUjEGWiIiIiGpUucOXsa5cwCBLRERERDXq3VYfZOMzC5FdWCZxNdUxyBIRERFRjewslejoZA0AiDTCXlkzqQsgIiIiIuN1r68TPFtbwlplfLHR+CoiIiIiIqMx535fqUu4JQ4tICIiIiKTxCBLRERERCaJQZaIiIiITBKDLBERERGZJAZZIiIiIjJJDLJEREREZJIYZImIiIjIJDHIEhEREZFJMoogu2zZMnh5eUGtViMwMBDHjh27bfuNGzfCx8cHarUafn5+2LFjh+F75eXleO211+Dn5wcrKyu4ublhwoQJSElJaey3QURERERNSPIgu2HDBoSFhWH+/PmIiopCjx49EBISgoyMjBrbHz58GOPGjcOUKVMQHR2N0NBQhIaG4syZMwCAoqIiREVF4c0330RUVBQ2bdqEuLg4jBo1qinfFhERERE1MpkQQkhZQGBgIAICArB06VIAgE6ng4eHB1544QXMnj27WvuxY8eisLAQ27ZtM5zr168fevbsieXLl9f4GsePH0ffvn1x9epVtG3b9o415eXlQaPRIDc3F7a2tvV8Z0RERERUV3XJYZL2yJaVlSEyMhLBwcGGc3K5HMHBwYiIiKjxmoiIiCrtASAkJOSW7QEgNzcXMpkMdnZ2DVI3EREREUnPTMoXz8rKglarhbOzc5Xzzs7OOH/+fI3XpKWl1dg+LS2txvYlJSV47bXXMG7cuFum+tLSUpSWlhq+zsvLq8vbICIiIiIJSBpkG1t5eTkef/xxCCHw5Zdf3rLdggUL8Pbbb1c7z0BLRERE1LQq81dtRr9KGmQdHBygUCiQnp5e5Xx6ejpcXFxqvMbFxaVW7StD7NWrV/Hnn3/edozFnDlzEBYWZvg6OTkZXbp0gYeHR13fEhERERE1gPz8fGg0mtu2kTTIKpVK+Pv7Izw8HKGhoQD0k73Cw8MxY8aMGq8JCgpCeHg4Zs6caTi3e/duBAUFGb6uDLEXL17E3r170bp169vWoVKpoFKpDF9bW1sjKSkJNjY2kMlk9X+DtZSXlwcPDw8kJSVxcpmJ4bMzXXx2povPzjTxuZmupn52Qgjk5+fDzc3tjm0lH1oQFhaGiRMnok+fPujbty+WLFmCwsJCTJ48GQAwYcIEuLu7Y8GCBQCAl156CYMHD8aiRYswcuRIrF+/HidOnMDXX38NQB9iH3vsMURFRWHbtm3QarWG8bP29vZQKpV3rEkul6NNmzaN9I5vzdbWln+4TRSfneniszNdfHamic/NdDXls7tTT2wlyYPs2LFjkZmZiXnz5iEtLQ09e/bEzp07DRO6EhMTIZf/vbhC//79sW7dOsydOxevv/46OnbsiC1btqBbt24A9MMCtm7dCgDo2bNnldfau3cvhgwZ0iTvi4iIiIgal+TryBLXrTVlfHami8/OdPHZmSY+N9NlzM9O8p29SD9Gd/78+VXG6ZJp4LMzXXx2povPzjTxuZkuY3527JElIiIiIpPEHlkiIiIiMkkMskRERERkkhhkiYiIiMgkMcg2kWXLlsHLywtqtRqBgYE4duzYbdtv3LgRPj4+UKvV8PPzw44dO5qoUvq3ujy7FStWYNCgQWjVqhVatWqF4ODgOz5rajx1/XNXaf369ZDJZIaNWqhp1fW55eTkYPr06XB1dYVKpUKnTp34d6ZE6vrslixZgs6dO8PCwgIeHh54+eWXUVJS0kTVUqUDBw7goYcegpubG2QyGbZs2XLHa/bt24fevXtDpVKhQ4cOWL16daPXWSNBjW79+vVCqVSKlStXirNnz4qpU6cKOzs7kZ6eXmP7Q4cOCYVCIT7++GNx7tw5MXfuXGFubi5Onz7dxJVTXZ/dk08+KZYtWyaio6NFbGysmDRpktBoNOLatWtNXDnV9dlVSkhIEO7u7mLQoEHi4YcfbppiyaCuz620tFT06dNHPPDAA+LgwYMiISFB7Nu3T8TExDRx5VTXZ7d27VqhUqnE2rVrRUJCgti1a5dwdXUVL7/8chNXTjt27BBvvPGG2LRpkwAgNm/efNv28fHxwtLSUoSFhYlz586JL774QigUCrFz586mKfgfGGSbQN++fcX06dMNX2u1WuHm5iYWLFhQY/vHH39cjBw5ssq5wMBA8dxzzzVqnVRdXZ/dv1VUVAgbGxvx3XffNVaJdAv1eXYVFRWif//+4ptvvhETJ05kkJVAXZ/bl19+Kby9vUVZWVlTlUi3UNdnN336dHHvvfdWORcWFiYGDBjQqHXS7dUmyL766quia9euVc6NHTtWhISENGJlNePQgkZWVlaGyMhIBAcHG87J5XIEBwcjIiKixmsiIiKqtAeAkJCQW7anxlGfZ/dvRUVFKC8vh729fWOVSTWo77N755134OTkhClTpjRFmfQv9XluW7duRVBQEKZPnw5nZ2d069YNH3zwAbRabVOVTajfs+vfvz8iIyMNww/i4+OxY8cOPPDAA01SM9WfMeUUybeobe6ysrKg1WoNW+5WcnZ2xvnz52u8Ji0trcb2aWlpjVYnVVefZ/dvr732Gtzc3Kr9gafGVZ9nd/DgQXz77beIiYlpggqpJvV5bvHx8fjzzz/x1FNPYceOHbh06RL+85//oLy8HPPnz2+Ksgn1e3ZPPvkksrKyMHDgQAghUFFRgeeffx6vv/56U5RMd+FWOSUvLw/FxcWwsLBoslrYI0vUSD788EOsX78emzdvhlqtlrocuo38/HyMHz8eK1asgIODg9TlUB3odDo4OTnh66+/hr+/P8aOHYs33ngDy5cvl7o0uoN9+/bhgw8+wP/+9z9ERUVh06ZN2L59O959912pSyMTwh7ZRubg4ACFQoH09PQq59PT0+Hi4lLjNS4uLnVqT42jPs+u0sKFC/Hhhx9iz5496N69e2OWSTWo67O7fPkyrly5goceeshwTqfTAQDMzMwQFxeH9u3bN27RVK8/c66urjA3N4dCoTCc8/X1RVpaGsrKyqBUKhu1ZtKrz7N78803MX78eDzzzDMAAD8/PxQWFuLZZ5/FG2+8AbmcfW3G6lY5xdbWtkl7YwH2yDY6pVIJf39/hIeHG87pdDqEh4cjKCioxmuCgoKqtAeA3bt337I9NY76PDsA+Pjjj/Huu+9i586d6NOnT1OUSv9S12fn4+OD06dPIyYmxnCMGjUKQ4cORUxMDDw8PJqy/BarPn/mBgwYgEuXLhn+4wEAFy5cgKurK0NsE6rPsysqKqoWViv/QyKEaLxi6a4ZVU5p8ullLdD69euFSqUSq1evFufOnRPPPvussLOzE2lpaUIIIcaPHy9mz55taH/o0CFhZmYmFi5cKGJjY8X8+fO5/JZE6vrsPvzwQ6FUKsXPP/8sUlNTDUd+fr5Ub6HFquuz+zeuWiCNuj63xMREYWNjI2bMmCHi4uLEtm3bhJOTk3jvvfekegstVl2f3fz584WNjY348ccfRXx8vPjjjz9E+/btxeOPPy7VW2ix8vPzRXR0tIiOjhYAxOLFi0V0dLS4evWqEEKI2bNni/HjxxvaVy6/NWvWLBEbGyuWLVvG5beauy+++EK0bdtWKJVK0bdvX3HkyBHD9wYPHiwmTpxYpf1PP/0kOnXqJJRKpejatavYvn17E1dMlery7Dw9PQWAasf8+fObvnCq85+7f2KQlU5dn9vhw4dFYGCgUKlUwtvbW7z//vuioqKiiasmIer27MrLy8Vbb70l2rdvL9RqtfDw8BD/+c9/xI0bN5q+8BZu7969Nf7bVfm8Jk6cKAYPHlztmp49ewqlUim8vb3FqlWrmrxuIYSQCcH+eyIiIiIyPRwjS0REREQmiUGWiIiIiEwSgywRERERmSQGWSIiIiIySQyyRERERGSSGGSJiIiIyCQxyBIRERGRSWKQJSIiIiKTxCBLRNSEJk2ahNDQ0Fq1vXLlCmQyGWJiYm7ZZvXq1bCzs2uQ2oiITA2DLBFRPdQlkP7TZ599htWrVzdYHWPHjsWFCxca7H53QyaTYcuWLVKXQUQtiJnUBRARtSQajaZB72dhYQELC4sGvWdjKisrg1KplLoMImom2CNLRHQbP//8M/z8/GBhYYHWrVsjODgYs2bNwnfffYdff/0VMpkMMpkM+/btAwCcPn0a9957r6H9s88+i4KCAsP9/t2Tq9Pp8PHHH6NDhw5QqVRo27Yt3n///So1xMfHY+jQobC0tESPHj0QERFh+F5NQwu+/PJLtG/fHkqlEp07d8aaNWuqfF8mk+Grr77Cgw8+CEtLS/j6+iIiIgKXLl3CkCFDYGVlhf79++Py5ctVrvv111/Ru3dvqNVqeHt74+2330ZFRQUAwMvLCwDwyCOPQCaTGb5+66230LNnT3zzzTdo164d1Go1vv/+e7Ru3RqlpaVV7h8aGorx48fX6rkQEQEABBER1SglJUWYmZmJxYsXi4SEBHHq1CmxbNkykZ+fLx5//HExYsQIkZqaKlJTU0VpaakoKCgQrq6u4tFHHxWnT58W4eHhol27dmLixImGe06cOFE8/PDDhq9fffVV0apVK7F69Wpx6dIl8ddff4kVK1YIIYRISEgQAISPj4/Ytm2biIuLE4899pjw9PQU5eXlQgghVq1aJTQajeF+mzZtEubm5mLZsmUiLi5OLFq0SCgUCvHnn38a2gAQ7u7uYsOGDSIuLk6EhoYKLy8vce+994qdO3eKc+fOiX79+okRI0YYrjlw4ICwtbUVq1evFpcvXxZ//PGH8PLyEm+99ZYQQoiMjAwBQKxatUqkpqaKjIwMIYQQ8+fPF1ZWVmLEiBEiKipKnDx5UhQVFQmNRiN++uknw/3T09OFmZlZlTqJiO6EQZaI6BYiIyMFAHHlypVq3/t3IBVCiK+//lq0atVKFBQUGM5t375dyOVykZaWVu26vLw8oVKpDMH13yqD7DfffGM4d/bsWQFAxMbGCiGqB9n+/fuLqVOnVrnPmDFjxAMPPGD4GoCYO3eu4euIiAgBQHz77beGcz/++KNQq9WGr4cNGyY++OCDKvdds2aNcHV1rXLfzZs3V2kzf/58YW5ubgi2laZNmybuv/9+w9eLFi0S3t7eQqfT1fhrQURUEw4tICK6hR49emDYsGHw8/PDmDFjsGLFCty4ceOW7WNjY9GjRw9YWVkZzg0YMAA6nQ5xcXE1ti8tLcWwYcNuW0f37t0Nn7u6ugIAMjIyblnDgAEDqpwbMGAAYmNjb3lPZ2dnAICfn1+VcyUlJcjLywMAnDx5Eu+88w6sra0Nx9SpU5GamoqioqLb1u/p6QlHR8cq56ZOnYo//vgDycnJAPRDJCZNmgSZTHbbexER/RMnexER3YJCocDu3btx+PBh/PHHH/jiiy/wxhtv4OjRow1y/9pO0jI3Nzd8Xhn0dDrdXb12Tfe83esUFBTg7bffxqOPPlrtXmq1+rav9c9gX6lXr17o0aMHvv/+ewwfPhxnz57F9u3b6/5GiKhFY48sEdFtyGQyDBgwAG+//Taio6OhVCqxefNmKJVKaLXaKm19fX1x8uRJFBYWGs4dOnQIcrkcnTt3rnbvjh07wsLCAuHh4Q1Wr6+vLw4dOlTl3KFDh9ClS5e7um/v3r0RFxeHDh06VDvkcv0/Jebm5tV+TW7nmWeewerVq7Fq1SoEBwfDw8PjrmokopaHPbJERLdw9OhRhIeHY/jw4XBycsLRo0eRmZkJX19flJSUYNeuXYiLi0Pr1q2h0Wjw1FNPYf78+Zg4cSLeeustZGZm4oUXXsD48eMNP77/J7Vajddeew2vvvoqlEolBgwYgMzMTJw9exZTpkypV82zZs3C448/jl69eiE4OBi//fYbNm3ahD179tzVr8W8efPw4IMPom3btnjssccgl8tx8uRJnDlzBu+99x4A/coF4eHhGDBgAFQqFVq1anXbez755JN45ZVXsGLFCnz//fd3VR8RtUzskSUiugVbW1scOHAADzzwADp16oS5c+di0aJFuP/++zF16lR07twZffr0gaOjIw4dOgRLS0vs2rUL2dnZCAgIwGOPPYZhw4Zh6dKlt3yNN998E//9738xb948+Pr6YuzYsbcc/1oboaGh+Oyzz7Bw4UJ07doVX331FVatWoUhQ4bU+54AEBISgm3btuGPP/5AQEAA+vXrh08//RSenp6GNosWLcLu3bvh4eGBXr163fGeGo0Go0ePhrW1db02lyAikgkhhNRFEBFRyzRs2DB07doVn3/+udSlEJEJYpAlIqImd+PGDezbtw+PPfYYzp07V+MYYiKiO+EYWSIianK9evXCjRs38NFHHzHEElG9sUeWiIiIiEwSJ3sRERERkUlikCUiIiIik8QgS0REREQmiUGWiIiIiEwSgywRERERmSQGWSIiIiIySQyyRERERGSSGGSJiIiIyCQxyBIRERGRSfp/7rwmLZVWW4cAAAAASUVORK5CYII=", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "import numpy as np\n", - "\n", - "sto_array = pybamm.Array(np.linspace(0, 1, 101))\n", - "sto = sto_array.entries\n", - "\n", - "ocp_avg_values = ocp_avg(sto_array).evaluate()\n", - "ocp_lithiation_values = lithiation_ocp(sto_array).evaluate()\n", - "ocp_delithiation_values = delithiation_ocp(sto_array).evaluate()\n", - "\n", - "hysteresis_values = hysteresis(sto_array).evaluate()\n", - "plt.subplots(2, 1, sharex=True, figsize=(7, 8))\n", - "plt.subplot(2, 1, 1)\n", - "plt.plot(sto, ocp_avg_values, label=\"OCP average\")\n", - "plt.plot(sto, ocp_lithiation_values, label=\"OCP lithiation\")\n", - "plt.plot(sto, ocp_delithiation_values, label=\"OCP delithiation\")\n", - "plt.ylabel(\"Voltage [V]\")\n", - "plt.legend()\n", - "plt.subplot(2, 1, 2)\n", - "plt.plot(sto, hysteresis_values, label=\"OCP hysteresis\")\n", - "plt.xlabel(\"stoichiometry\")\n", - "plt.ylabel(\"Voltage [V]\")\n", - "plt.legend()\n", - "plt.tight_layout()\n", - "plt.show()" - ] - }, { "cell_type": "markdown", "metadata": {}, @@ -191,7 +133,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ @@ -239,13 +181,13 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "2344463a0a7f4455bf5a4656a9dddbfa", + "model_id": "7fa481d981ff4f9da3b688120bdbf930", "version_major": 2, "version_minor": 0 }, @@ -271,13 +213,13 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "b2ae424fa5524d55b82350d1ec5aa40f", + "model_id": "6745f5d4c7e64bbc8a57011b282bdf2e", "version_major": 2, "version_minor": 0 }, diff --git a/pybamm/models/submodels/interface/open_circuit_potential/wycisk_ocp.py b/pybamm/models/submodels/interface/open_circuit_potential/wycisk_ocp.py index 43b13e6d3b..32211f66b1 100644 --- a/pybamm/models/submodels/interface/open_circuit_potential/wycisk_ocp.py +++ b/pybamm/models/submodels/interface/open_circuit_potential/wycisk_ocp.py @@ -26,12 +26,26 @@ def get_fundamental_variables(self): f"{Domain} electrode {phase_name}hysteresis state": h, } + def Q(self, sto, epsilon_s_av): + """Capacity change as a function of stoichiometry""" + c_max = self.phase_param.c_max + # epsilon_s_av = self.epsilon_s_av + epsilon_s_av = pybamm.yz_average(epsilon_s_av) + V_electrode = self.phase_param.main_param.A_cc * self.domain_param.L + Li_max = c_max * V_electrode * epsilon_s_av + Q_max = Li_max * self.phase_param.main_param.F / 3600 + return Q_max * sto + def get_coupled_variables(self, variables): domain, Domain = self.domain_Domain phase_name = self.phase_name phase = self.phase if self.reaction == "lithium-ion main": + # define custom hysteresis function + # hysteresis = pybamm.FunctionParameter(f'{Domain} {phase_name}particle hysteresis [V]') + # sto = variables[f'{Domain} {phase_name} particle stoichiometry'] + T = variables[f"{Domain} electrode temperature [K]"] h = variables[f"{Domain} electrode {phase_name}hysteresis state"] @@ -83,11 +97,34 @@ def get_coupled_variables(self, variables): ocp_bulk_eq ) - H = self.phase_param.hysteresis(sto_surf) + inputs = {f"{Domain} {phase_name}particle stoichiometry": sto_surf} + lith_ref = pybamm.FunctionParameter( + f"{self.phase_param.phase_prefactor}{Domain} electrode lithiation OCP [V]", + inputs, + ) + delith_ref = pybamm.FunctionParameter( + f"{self.phase_param.phase_prefactor}{Domain} electrode delithiation OCP [V]", + inputs, + ) + H = abs(delith_ref - lith_ref) / 2 variables[f"{Domain} electrode {phase_name}OCP hysteresis [V]"] = H + # determine dQ/dU + def Q(sto, epsilon_s_av): + """Capacity change as a function of stoichiometry and active material volume fraction""" + c_max = self.phase_param.c_max + # epsilon_s_av = self.epsilon_s_av + epsilon_s_av = pybamm.yz_average(epsilon_s_av) + V_electrode = self.phase_param.main_param.A_cc * self.domain_param.L + Li_max = c_max * V_electrode * epsilon_s_av + Q_max = Li_max * self.phase_param.main_param.F / 3600 + return Q_max * sto + dU = self.phase_param.U(sto_surf, T_bulk).diff(sto_surf) - dQ = self.phase_param.Q(sto_surf).diff(sto_surf) + epsilon_s_av = variables[ + f"X-averaged {domain} electrode {phase_name}active material volume fraction" + ] + dQ = Q(sto_surf, epsilon_s_av).diff(sto_surf) dQdU = dQ / dU variables[ f"{Domain} electrode {phase_name}differential capacity [A.s.V-1]" diff --git a/pybamm/parameters/lithium_ion_parameters.py b/pybamm/parameters/lithium_ion_parameters.py index 43e33679e6..72eb6534da 100644 --- a/pybamm/parameters/lithium_ion_parameters.py +++ b/pybamm/parameters/lithium_ion_parameters.py @@ -649,33 +649,6 @@ def U(self, sto, T, lithiation=None): out.print_name = r"U_\mathrm{p}(c^\mathrm{surf}_\mathrm{s,p}, T)" return out - def hysteresis(self, sto): - """Dimensional hysteresis [V]""" - Domain = self.domain.capitalize() - # tol = pybamm.settings.tolerances["U__c_s"] - # sto = pybamm.maximum(pybamm.minimum(sto,1-tol),tol) - inputs = {f"{self.phase_prefactor}{Domain} particle stoichiometry": sto} - lith_ref = pybamm.FunctionParameter( - f"{self.phase_prefactor}{Domain} electrode lithiation OCP [V]", inputs - ) - delith_ref = pybamm.FunctionParameter( - f"{self.phase_prefactor}{Domain} electrode delithiation OCP [V]", inputs - ) - h_ref = abs(delith_ref - lith_ref) / 2 - # h_ref = pybamm.FunctionParameter( - # f"{self.phase_prefactor}{Domain} electrode OCP hysteresis [V]", inputs - # ) - return h_ref - - def Q(self, sto): - """Capacity change as a function of stoichiometry""" - c_max = self.c_max - epsilon_s_av = self.epsilon_s_av - V_electrode = self.main_param.A_cc * self.domain_param.L - Li_max = c_max * V_electrode * epsilon_s_av - Q_max = Li_max * self.main_param.F / 3600 - return Q_max * sto - def dUdT(self, sto): """ Dimensional entropic change of the open-circuit potential [V.K-1] From 1a8268caa901252bc81d3d16302ff08271a14c76 Mon Sep 17 00:00:00 2001 From: Tanner Leo Date: Thu, 9 May 2024 15:26:23 -0700 Subject: [PATCH 42/43] fix change requests --- ...fferential-capacity-hysteresis-state.ipynb | 4 +- .../open_circuit_potential/wycisk_ocp.py | 47 ++++++++----------- 2 files changed, 22 insertions(+), 29 deletions(-) diff --git a/docs/source/examples/notebooks/models/differential-capacity-hysteresis-state.ipynb b/docs/source/examples/notebooks/models/differential-capacity-hysteresis-state.ipynb index f3bda4a98c..70bf2da2a9 100644 --- a/docs/source/examples/notebooks/models/differential-capacity-hysteresis-state.ipynb +++ b/docs/source/examples/notebooks/models/differential-capacity-hysteresis-state.ipynb @@ -187,7 +187,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "7fa481d981ff4f9da3b688120bdbf930", + "model_id": "89b75271238a4f06989508291e6e65b7", "version_major": 2, "version_minor": 0 }, @@ -219,7 +219,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "6745f5d4c7e64bbc8a57011b282bdf2e", + "model_id": "e0dfb494d90546eeb6dfd900ca377ce4", "version_major": 2, "version_minor": 0 }, diff --git a/pybamm/models/submodels/interface/open_circuit_potential/wycisk_ocp.py b/pybamm/models/submodels/interface/open_circuit_potential/wycisk_ocp.py index 32211f66b1..05cdda7f7c 100644 --- a/pybamm/models/submodels/interface/open_circuit_potential/wycisk_ocp.py +++ b/pybamm/models/submodels/interface/open_circuit_potential/wycisk_ocp.py @@ -26,26 +26,12 @@ def get_fundamental_variables(self): f"{Domain} electrode {phase_name}hysteresis state": h, } - def Q(self, sto, epsilon_s_av): - """Capacity change as a function of stoichiometry""" - c_max = self.phase_param.c_max - # epsilon_s_av = self.epsilon_s_av - epsilon_s_av = pybamm.yz_average(epsilon_s_av) - V_electrode = self.phase_param.main_param.A_cc * self.domain_param.L - Li_max = c_max * V_electrode * epsilon_s_av - Q_max = Li_max * self.phase_param.main_param.F / 3600 - return Q_max * sto - def get_coupled_variables(self, variables): domain, Domain = self.domain_Domain phase_name = self.phase_name phase = self.phase if self.reaction == "lithium-ion main": - # define custom hysteresis function - # hysteresis = pybamm.FunctionParameter(f'{Domain} {phase_name}particle hysteresis [V]') - # sto = variables[f'{Domain} {phase_name} particle stoichiometry'] - T = variables[f"{Domain} electrode temperature [K]"] h = variables[f"{Domain} electrode {phase_name}hysteresis state"] @@ -110,21 +96,28 @@ def get_coupled_variables(self, variables): variables[f"{Domain} electrode {phase_name}OCP hysteresis [V]"] = H # determine dQ/dU - def Q(sto, epsilon_s_av): - """Capacity change as a function of stoichiometry and active material volume fraction""" - c_max = self.phase_param.c_max - # epsilon_s_av = self.epsilon_s_av - epsilon_s_av = pybamm.yz_average(epsilon_s_av) - V_electrode = self.phase_param.main_param.A_cc * self.domain_param.L - Li_max = c_max * V_electrode * epsilon_s_av - Q_max = Li_max * self.phase_param.main_param.F / 3600 - return Q_max * sto + # def Q(sto, epsilon_s_av): + # """Capacity change as a function of stoichiometry and active material volume fraction""" + # c_max = self.phase_param.c_max + # # epsilon_s_av = self.epsilon_s_av + # epsilon_s_av = pybamm.yz_average(epsilon_s_av) + # V_electrode = self.phase_param.main_param.A_cc * self.domain_param.L + # Li_max = c_max * V_electrode * epsilon_s_av + # Q_max = Li_max * self.phase_param.main_param.F / 3600 + # return Q_max * sto + + def Q(sto): + """Capacity change as a function of stoichiometry""" + if phase_name == "": + C = variables[f"{Domain} electrode capacity [A.h]"] + else: + C = variables[ + f"{Domain} electrode {phase_name}phase capacity [A.h]" + ] + return C * sto dU = self.phase_param.U(sto_surf, T_bulk).diff(sto_surf) - epsilon_s_av = variables[ - f"X-averaged {domain} electrode {phase_name}active material volume fraction" - ] - dQ = Q(sto_surf, epsilon_s_av).diff(sto_surf) + dQ = Q(sto_surf).diff(sto_surf) dQdU = dQ / dU variables[ f"{Domain} electrode {phase_name}differential capacity [A.s.V-1]" From f6fc3adbd018e4436fa3d22316dc410f7d196e57 Mon Sep 17 00:00:00 2001 From: Tanner Leo Date: Fri, 10 May 2024 17:08:34 -0700 Subject: [PATCH 43/43] getting rid of functional form Q --- ...fferential-capacity-hysteresis-state.ipynb | 4 +-- .../open_circuit_potential/wycisk_ocp.py | 28 +++++-------------- 2 files changed, 9 insertions(+), 23 deletions(-) diff --git a/docs/source/examples/notebooks/models/differential-capacity-hysteresis-state.ipynb b/docs/source/examples/notebooks/models/differential-capacity-hysteresis-state.ipynb index 70bf2da2a9..3a3bb81a53 100644 --- a/docs/source/examples/notebooks/models/differential-capacity-hysteresis-state.ipynb +++ b/docs/source/examples/notebooks/models/differential-capacity-hysteresis-state.ipynb @@ -187,7 +187,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "89b75271238a4f06989508291e6e65b7", + "model_id": "e6677ed985c14dd8941223b20650f6fd", "version_major": 2, "version_minor": 0 }, @@ -219,7 +219,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "e0dfb494d90546eeb6dfd900ca377ce4", + "model_id": "51ea98d2812c4afd97b1b9c33ee95eef", "version_major": 2, "version_minor": 0 }, diff --git a/pybamm/models/submodels/interface/open_circuit_potential/wycisk_ocp.py b/pybamm/models/submodels/interface/open_circuit_potential/wycisk_ocp.py index 05cdda7f7c..2a79c78a48 100644 --- a/pybamm/models/submodels/interface/open_circuit_potential/wycisk_ocp.py +++ b/pybamm/models/submodels/interface/open_circuit_potential/wycisk_ocp.py @@ -96,29 +96,15 @@ def get_coupled_variables(self, variables): variables[f"{Domain} electrode {phase_name}OCP hysteresis [V]"] = H # determine dQ/dU - # def Q(sto, epsilon_s_av): - # """Capacity change as a function of stoichiometry and active material volume fraction""" - # c_max = self.phase_param.c_max - # # epsilon_s_av = self.epsilon_s_av - # epsilon_s_av = pybamm.yz_average(epsilon_s_av) - # V_electrode = self.phase_param.main_param.A_cc * self.domain_param.L - # Li_max = c_max * V_electrode * epsilon_s_av - # Q_max = Li_max * self.phase_param.main_param.F / 3600 - # return Q_max * sto - - def Q(sto): - """Capacity change as a function of stoichiometry""" - if phase_name == "": - C = variables[f"{Domain} electrode capacity [A.h]"] - else: - C = variables[ - f"{Domain} electrode {phase_name}phase capacity [A.h]" - ] - return C * sto + if phase_name == "": + Q_mag = variables[f"{Domain} electrode capacity [A.h]"] + else: + Q_mag = variables[ + f"{Domain} electrode {phase_name}phase capacity [A.h]" + ] dU = self.phase_param.U(sto_surf, T_bulk).diff(sto_surf) - dQ = Q(sto_surf).diff(sto_surf) - dQdU = dQ / dU + dQdU = Q_mag / dU variables[ f"{Domain} electrode {phase_name}differential capacity [A.s.V-1]" ] = dQdU