Source code for pybamm.models.submodels.active_material.base_active_material
#
# Base class for active material volume fraction
#
import pybamm
[docs]
class BaseModel(pybamm.BaseSubModel):
"""Base class for active material volume fraction
Parameters
----------
param : parameter class
The parameters to use for this submodel
domain : str
The domain of the model either 'Negative' or 'Positive'
options : dict
Additional options to pass to the model
phase : str, optional
Phase of the particle (default is "primary")
"""
def __init__(self, param, domain, options, phase="primary"):
super().__init__(param, domain, options=options, phase=phase)
def _get_standard_active_material_variables(self, eps_solid):
phase_name = self.phase_name
domain, Domain = self.domain_Domain
if eps_solid.domain == []:
eps_solid = pybamm.PrimaryBroadcast(eps_solid, "current collector")
if eps_solid.domain == ["current collector"]:
eps_solid = pybamm.PrimaryBroadcast(eps_solid, f"{domain} electrode")
eps_solid_av = pybamm.x_average(eps_solid)
variables = {
f"{Domain} electrode {phase_name}"
"active material volume fraction": eps_solid,
f"X-averaged {domain} electrode {phase_name}"
"active material volume fraction": eps_solid_av,
}
# Update other microstructure variables
# some models (e.g. lead-acid) do not have particles
if self.options["particle shape"] == "no particles":
a = self.phase_param.a
variables.update(
{
f"{Domain} electrode surface area to volume ratio [m-1]": a,
f"X-averaged {domain} electrode surface area "
"to volume ratio [m-1]": pybamm.x_average(a),
}
)
return variables
else:
# Update electrode capacity variables
L = self.domain_param.L
c_s_max = self.phase_param.c_max
C = (
pybamm.yz_average(eps_solid_av)
* L
* self.param.A_cc
* c_s_max
* self.param.F
/ 3600
)
if phase_name == "":
variables.update({f"{Domain} electrode capacity [A.h]": C})
else:
variables.update(
{f"{Domain} electrode {phase_name}phase capacity [A.h]": C}
)
# If a single particle size at every x, use the parameters
# R_n, R_p. For a size distribution, calculate the area-weighted
# mean using the distribution instead. Then the surface area is
# calculated the same way
domain_options = getattr(self.options, domain)
if domain_options["particle size"] == "single":
R = self.phase_param.R
elif domain_options["particle size"] == "distribution":
if self.domain == "negative":
if self.phase_name == "primary ":
R_ = pybamm.standard_spatial_vars.R_n_prim
elif self.phase_name == "secondary ":
R_ = pybamm.standard_spatial_vars.R_n_sec
else:
R_ = pybamm.standard_spatial_vars.R_n
elif self.domain == "positive":
if self.phase_name == "primary ":
R_ = pybamm.standard_spatial_vars.R_p_prim
elif self.phase_name == "secondary ":
R_ = pybamm.standard_spatial_vars.R_p_sec
else:
R_ = pybamm.standard_spatial_vars.R_p
R = pybamm.size_average(R_)
R_av = pybamm.x_average(R)
# Compute dimensional particle shape
if self.options["particle shape"] == "spherical":
a = 3 * eps_solid / R
a_av = pybamm.x_average(a)
a.print_name = f"a_{domain[0]}"
a_av.print_name = f"a_av_{domain[0]}"
variables.update(
{
f"{Domain} {phase_name}particle radius": R / self.phase_param.R_typ,
f"{Domain} {phase_name}particle radius [m]": R,
f"X-averaged {domain} {phase_name}particle radius [m]": R_av,
f"{Domain} electrode {phase_name}"
"surface area to volume ratio [m-1]": a,
f"X-averaged {domain} electrode {phase_name}"
"surface area to volume ratio [m-1]": a_av,
}
)
return variables
def _get_standard_active_material_change_variables(self, deps_solid_dt):
domain, Domain = self.domain_Domain
if deps_solid_dt.domain == ["current collector"]:
deps_solid_dt_av = deps_solid_dt
deps_solid_dt = pybamm.PrimaryBroadcast(
deps_solid_dt_av, f"{domain} electrode"
)
else:
deps_solid_dt_av = pybamm.x_average(deps_solid_dt)
variables = {
f"{Domain} electrode {self.phase_name}"
"active material volume fraction change [s-1]": deps_solid_dt,
f"X-averaged {domain} electrode {self.phase_name}"
"active material volume fraction change [s-1]": deps_solid_dt_av,
}
return variables