Skip to content

Commit

Permalink
#2418 fixed SPM, fixed diffusion models
Browse files Browse the repository at this point in the history
  • Loading branch information
valentinsulzer committed Nov 6, 2022
1 parent f806319 commit e5e84a5
Show file tree
Hide file tree
Showing 14 changed files with 90 additions and 86 deletions.
5 changes: 3 additions & 2 deletions examples/scripts/compare_lithium_ion.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@

# load models
models = [
# pybamm.lithium_ion.BasicSPM(),
pybamm.lithium_ion.SPM(),
pybamm.lithium_ion.SPMe(),
pybamm.lithium_ion.DFN(),
pybamm.lithium_ion.NewmanTobias(),
# pybamm.lithium_ion.DFN(),
# pybamm.lithium_ion.NewmanTobias(),
]

# create and run simulations
Expand Down
6 changes: 3 additions & 3 deletions pybamm/models/full_battery_models/lithium_ion/basic_spm.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,8 @@ def __init__(self, name="Single Particle Model"):
######################
# Interfacial reactions
RT_F = param.R * T / param.F
j0_n = param.n.prim.j0(1, c_s_surf_n, T)
j0_p = param.p.prim.j0(1, c_s_surf_p, T)
j0_n = param.n.prim.j0(param.c_e_typ, c_s_surf_n, T)
j0_p = param.p.prim.j0(param.c_e_typ, c_s_surf_p, T)
eta_n = (2 / param.n.prim.ne) * RT_F * pybamm.arcsinh(j_n / (2 * j0_n))
eta_p = (2 / param.p.prim.ne) * RT_F * pybamm.arcsinh(j_p / (2 * j0_p))
phi_s_n = 0
Expand All @@ -159,7 +159,7 @@ def __init__(self, name="Single Particle Model"):
c_s_surf_n, "negative electrode"
),
"Electrolyte concentration [mol.m-3]": pybamm.PrimaryBroadcast(
1, whole_cell
param.c_e_typ, whole_cell
),
"Positive particle surface "
"concentration [mol.m-3]": pybamm.PrimaryBroadcast(
Expand Down
82 changes: 41 additions & 41 deletions pybamm/models/full_battery_models/lithium_ion/spme.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,52 +67,52 @@ def set_transport_efficiency_submodels(self):
"electrode transport efficiency"
] = pybamm.transport_efficiency.Bruggeman(self.param, "Electrode", self.options)

def set_solid_submodel(self):
for domain in ["negative", "positive"]:
if self.options.electrode_types[domain] == "porous":
solid_submodel = pybamm.electrode.ohm.Composite
elif self.options.electrode_types[domain] == "planar":
if self.options["surface form"] == "false":
solid_submodel = pybamm.electrode.ohm.LithiumMetalExplicit
else:
solid_submodel = pybamm.electrode.ohm.LithiumMetalSurfaceForm
self.submodels[f"{domain} electrode potential [V]"] = solid_submodel(
self.param, domain, self.options
)
# def set_solid_submodel(self):
# for domain in ["negative", "positive"]:
# if self.options.electrode_types[domain] == "porous":
# solid_submodel = pybamm.electrode.ohm.Composite
# elif self.options.electrode_types[domain] == "planar":
# if self.options["surface form"] == "false":
# solid_submodel = pybamm.electrode.ohm.LithiumMetalExplicit
# else:
# solid_submodel = pybamm.electrode.ohm.LithiumMetalSurfaceForm
# self.submodels[f"{domain} electrode potential [V]"] = solid_submodel(
# self.param, domain, self.options
# )

def set_electrolyte_concentration_submodel(self):
self.submodels["electrolyte diffusion"] = pybamm.electrolyte_diffusion.Full(
self.param, self.options
)

def set_electrolyte_potential_submodel(self):
surf_form = pybamm.electrolyte_conductivity.surface_potential_form
# def set_electrolyte_potential_submodel(self):
# surf_form = pybamm.electrolyte_conductivity.surface_potential_form

if (
self.options["surface form"] == "false"
or self.options.electrode_types["negative"] == "planar"
):
if self.options["electrolyte conductivity"] in ["default", "composite"]:
self.submodels[
"electrolyte conductivity"
] = pybamm.electrolyte_conductivity.Composite(
self.param, options=self.options
)
elif self.options["electrolyte conductivity"] == "integrated":
self.submodels[
"electrolyte conductivity"
] = pybamm.electrolyte_conductivity.Integrated(
self.param, options=self.options
)
if self.options["surface form"] == "false":
surf_model = surf_form.Explicit
elif self.options["surface form"] == "differential":
surf_model = surf_form.CompositeDifferential
elif self.options["surface form"] == "algebraic":
surf_model = surf_form.CompositeAlgebraic
# if (
# self.options["surface form"] == "false"
# or self.options.electrode_types["negative"] == "planar"
# ):
# if self.options["electrolyte conductivity"] in ["default", "composite"]:
# self.submodels[
# "electrolyte conductivity"
# ] = pybamm.electrolyte_conductivity.Composite(
# self.param, options=self.options
# )
# elif self.options["electrolyte conductivity"] == "integrated":
# self.submodels[
# "electrolyte conductivity"
# ] = pybamm.electrolyte_conductivity.Integrated(
# self.param, options=self.options
# )
# if self.options["surface form"] == "false":
# surf_model = surf_form.Explicit
# elif self.options["surface form"] == "differential":
# surf_model = surf_form.CompositeDifferential
# elif self.options["surface form"] == "algebraic":
# surf_model = surf_form.CompositeAlgebraic

for domain in ["negative", "positive"]:
if self.options.electrode_types[domain] == "porous":
self.submodels[
f"{domain} surface potential difference [V]"
] = surf_model(self.param, domain, self.options)
# for domain in ["negative", "positive"]:
# if self.options.electrode_types[domain] == "porous":
# self.submodels[
# f"{domain} surface potential difference [V]"
# ] = surf_model(self.param, domain, self.options)
9 changes: 5 additions & 4 deletions pybamm/models/submodels/electrode/ohm/leading_ohm.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,15 @@ def get_coupled_variables(self, variables):
phi_s_cn = variables["Negative current collector potential [V]"]

# import parameters and spatial variables
l_n = param.n.L
l_p = param.p.L
L_n = param.n.L
L_p = param.p.L
L_x = param.L_x
x_n = pybamm.standard_spatial_vars.x_n
x_p = pybamm.standard_spatial_vars.x_p

if self.domain == "negative":
phi_s = pybamm.PrimaryBroadcast(phi_s_cn, "negative electrode")
i_s = i_boundary_cc * (1 - x_n / l_n)
i_s = i_boundary_cc * (1 - x_n / L_n)

elif self.domain == "positive":
# recall delta_phi = phi_s - phi_e
Expand All @@ -62,7 +63,7 @@ def get_coupled_variables(self, variables):
v = delta_phi_p_av + phi_e_p_av

phi_s = pybamm.PrimaryBroadcast(v, ["positive electrode"])
i_s = i_boundary_cc * (1 - (1 - x_p) / l_p)
i_s = i_boundary_cc * (1 - (L_x - x_p) / L_p)

variables.update(self._get_standard_potential_variables(phi_s))
variables.update(self._get_standard_current_variables(i_s))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ def get_coupled_variables(self, variables):
L_n = param.n.L
L_s = param.s.L
L_p = param.p.L
L_x = param.L_x
x_s = pybamm.standard_spatial_vars.x_s
x_p = pybamm.standard_spatial_vars.x_p

Expand All @@ -84,7 +85,7 @@ def get_coupled_variables(self, variables):
kappa_n_av = param.kappa_e(c_e_av, T_av) * tor_n_av
i_e_n = i_boundary_cc * x_n / L_n
i_e_s = pybamm.PrimaryBroadcast(i_boundary_cc, "separator")
i_e_p = i_boundary_cc * (1 - x_p) / L_p
i_e_p = i_boundary_cc * (L_x - x_p) / L_p
i_e = pybamm.concatenation(i_e_n, i_e_s, i_e_p)

phi_e_dict = {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ def get_coupled_variables(self, variables):
param = self.param
L_n = param.n.L
L_p = param.p.L
L_x = param.L_x
x_n = pybamm.standard_spatial_vars.x_n
x_s = pybamm.standard_spatial_vars.x_s
x_p = pybamm.standard_spatial_vars.x_p
Expand All @@ -84,12 +85,12 @@ def get_coupled_variables(self, variables):
# electrolyte current
i_e_n = i_boundary_cc * x_n / L_n
i_e_s = pybamm.PrimaryBroadcast(i_boundary_cc, "separator")
i_e_p = i_boundary_cc * (1 - x_p) / L_p
i_e_p = i_boundary_cc * (L_x - x_p) / L_p
i_e = pybamm.concatenation(i_e_n, i_e_s, i_e_p)

i_e_n_edge = i_boundary_cc * x_n_edge / L_n
i_e_s_edge = pybamm.PrimaryBroadcastToEdges(i_boundary_cc, "separator")
i_e_p_edge = i_boundary_cc * (1 - x_p_edge) / L_p
i_e_p_edge = i_boundary_cc * (L_x - x_p_edge) / L_p

# electrolyte potential
indef_integral_n = pybamm.IndefiniteIntegral(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,23 +39,24 @@ def get_coupled_variables(self, variables):
i_boundary_cc = variables["Current collector current density [A.m-2]"]

param = self.param
l_n = param.n.L
l_p = param.p.L
L_n = param.n.L
L_p = param.p.L
L_x = param.L_x
x_n = pybamm.standard_spatial_vars.x_n
x_p = pybamm.standard_spatial_vars.x_p

if "negative electrode" not in self.options.whole_cell_domains:
i_e_n = None
else:
i_e_n = i_boundary_cc * x_n / l_n
i_e_n = i_boundary_cc * x_n / L_n

phi_e_dict = {
domain: pybamm.PrimaryBroadcast(phi_e_av, domain)
for domain in self.options.whole_cell_domains
}

i_e_s = pybamm.PrimaryBroadcast(i_boundary_cc, ["separator"])
i_e_p = i_boundary_cc * (1 - x_p) / l_p
i_e_p = i_boundary_cc * (L_x - x_p) / L_p
i_e = pybamm.concatenation(i_e_n, i_e_s, i_e_p)

variables.update(self._get_standard_potential_variables(phi_e_dict))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,13 @@ def _get_standard_concentration_variables(self, c_e_dict):
electrolyte.
"""

c_e_typ = self.param.c_e_typ
c_e = pybamm.concatenation(*c_e_dict.values())
# Override print_name
c_e.print_name = "c_e"

variables = {
"Electrolyte concentration": c_e,
"X-averaged electrolyte concentration": pybamm.x_average(c_e),
"Electrolyte concentration [mol.m-3]": c_e,
"X-averaged electrolyte concentration [mol.m-3]": pybamm.x_average(c_e),
}

# Case where an electrode is not included (half-cell)
Expand All @@ -58,18 +57,20 @@ def _get_standard_concentration_variables(self, c_e_dict):
c_e_k_av = pybamm.x_average(c_e_k)
variables.update(
{
f"{Domain} electrolyte concentration": c_e_k,
f"X-averaged {domain} electrolyte concentration": c_e_k_av,
f"{Domain} electrolyte concentration [mol.m-3]": c_e_k,
f"X-averaged {domain} electrolyte "
"concentration [mol.m-3]": c_e_k_av,
}
)

# Calculate dimensional variables
variables_nondim = variables.copy()
for name, var in variables_nondim.items():
# Calculate dimensionless and molar variables
variables_dim = variables.copy()
for name, var in variables_dim.items():
name = name.replace(" [mol.m-3]", "")
variables.update(
{
f"{name} [mol.m-3]": c_e_typ * var,
f"{name} [Molar]": c_e_typ * var / 1000,
name: var / self.param.c_e_typ,
f"{name} [Molar]": var / 1000,
}
)

Expand Down Expand Up @@ -119,16 +120,11 @@ def _get_total_concentration_electrolyte(self, eps_c_e):
variables : dict
The "Total lithium in electrolyte [mol]" variable.
"""

c_e_typ = self.param.c_e_typ
L_x = self.param.L_x
A = self.param.A_cc

eps_c_e_av = pybamm.yz_average(pybamm.x_average(eps_c_e))

variables = {
"Total lithium in electrolyte": eps_c_e_av,
"Total lithium in electrolyte [mol]": c_e_typ * L_x * A * eps_c_e_av,
}
variables = {"Total lithium in electrolyte [mol]": L_x * A * eps_c_e_av}

return variables
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ def __init__(self, param, options=None):
super().__init__(param, options)

def get_fundamental_variables(self):
c_e_init = self.param.c_e_init
c_e_dict = {
domain: pybamm.FullBroadcast(1, domain, "current collector")
domain: pybamm.FullBroadcast(c_e_init, domain, "current collector")
for domain in self.options.whole_cell_domains
}
variables = self._get_standard_concentration_variables(c_e_dict)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def get_fundamental_variables(self):
I = self.param.current_with_time

variables = {
"Current density variable": pybamm.Scalar(1, name="i_cell"),
"Current density variable [A.m-2]": i_cell,
"Total current density [A.m-2]": i_cell,
"Current [A]": I,
"C-rate": I / self.param.Q,
Expand Down
5 changes: 3 additions & 2 deletions pybamm/models/submodels/interface/base_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ def _get_exchange_current_density(self, variables):
# of c_s_surf that depends on particle size.
if self.options["particle size"] == "distribution":
c_s_surf = variables[
f"{Domain} {phase_name}particle surface concentration distribution"
f"{Domain} {phase_name}particle surface "
"concentration distribution [mol.m-3]"
]
# If all variables were broadcast (in "x"), take only the orphans,
# then re-broadcast c_e
Expand All @@ -97,7 +98,7 @@ def _get_exchange_current_density(self, variables):

else:
c_s_surf = variables[
f"{Domain} {phase_name}particle surface concentration"
f"{Domain} {phase_name}particle surface concentration [mol.m-3]"
]
# If all variables were broadcast, take only the orphans
if (
Expand Down
8 changes: 3 additions & 5 deletions pybamm/models/submodels/interface/sei/sei_growth.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,12 +160,10 @@ def get_coupled_variables(self, variables):
c_ec_av = pybamm.x_average(c_ec)

if self.reaction == "SEI on cracks":
name = "EC concentration on cracks"
name = "EC concentration on cracks [mol.m-3]"
else:
name = "EC surface concentration"
variables.update(
{f"{name} [mol.m-3]": c_ec, f"X-averaged {name} [mol.m-3]": c_ec_av}
)
name = "EC surface concentration [mol.m-3]"
variables.update({name: c_ec, f"X-averaged {name}": c_ec_av})

if self.options["SEI"].startswith("ec reaction limited"):
inner_sei_proportion = 0
Expand Down
9 changes: 6 additions & 3 deletions pybamm/models/submodels/particle/polynomial_profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ def get_fundamental_variables(self):
# We solve an equation for the surface concentration, so it is
# a variable in the model
c_s_surf = pybamm.Variable(
f"{Domain} particle surface concentration",
f"{Domain} particle surface concentration [mol.m-3]",
domain=f"{domain} electrode",
auxiliary_domains={"secondary": "current collector"},
bounds=(0, 1),
Expand All @@ -112,12 +112,15 @@ def get_fundamental_variables(self):
# distinction between the flux defined as N = -D*dc/dr and the
# concentration gradient q = dc/dr
q_s_rav = pybamm.Variable(
f"R-averaged {domain} particle concentration gradient",
f"R-averaged {domain} particle concentration gradient [mol.m-4]",
domain=f"{domain} electrode",
auxiliary_domains={"secondary": "current collector"},
)
variables.update(
{f"R-averaged {domain} particle concentration gradient": q_s_rav}
{
f"R-averaged {domain} particle "
"concentration gradient [mol.m-4]": q_s_rav
}
)

# Set concentration depending on polynomial order
Expand Down
2 changes: 1 addition & 1 deletion pybamm/parameters/lithium_ion_parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ def _set_parameters(self):

# Total lithium
# Electrolyte
c_e_av_init = pybamm.xyz_average(self.epsilon_init) * self.c_e_typ
c_e_av_init = pybamm.xyz_average(self.epsilon_init) * self.c_e_init
self.n_Li_e_init = c_e_av_init * self.L_x * self.A_cc

self.n_Li_particles_init = self.n.n_Li_init + self.p.n_Li_init
Expand Down

0 comments on commit e5e84a5

Please sign in to comment.