Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue 1253 reformat dfn half cell #1282

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## Features

- Reformatted the `BasicDFNHalfCell` to be consistent with the other models ([#1282](https://github.com/pybamm-team/PyBaMM/pull/1282))
- Added option to make the total interfacial current density a state ([#1280](https://github.com/pybamm-team/PyBaMM/pull/1280))
- Added functionality to initialize a model using the solution from another model ([#1278](https://github.com/pybamm-team/PyBaMM/pull/1278))
- Added submodels for active material ([#1262](https://github.com/pybamm-team/PyBaMM/pull/1262))
Expand All @@ -14,6 +15,7 @@
## Bug fixes

- Fixed `Simulation` and `model.new_copy` to fix a bug where changes to the model were overwritten ([#1278](https://github.com/pybamm-team/PyBaMM/pull/1278))

## Breaking changes

- Boolean model options ('sei porosity change', 'convection') must now be given in string format ('true' or 'false' instead of True or False) ([#1280](https://github.com/pybamm-team/PyBaMM/pull/1280))
Expand Down
21 changes: 12 additions & 9 deletions examples/scripts/DFN_half_cell.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,36 +28,39 @@
check_already_exists=False,
)

param["Initial concentration in negative electrode [mol.m-3]"] = 1000
param["Current function [A]"] = 2.5

# process model and geometry
param.process_model(model)
param.process_geometry(geometry)

# set mesh
var = pybamm.standard_spatial_vars
var_pts = {var.x_n: 30, var.x_s: 30, var.x_p: 30, var.r_n: 10, var.r_p: 10}
var_pts = model.default_var_pts
mesh = pybamm.Mesh(geometry, model.default_submesh_types, var_pts)

# discretise model
disc = pybamm.Discretisation(mesh, model.default_spatial_methods)
disc.process_model(model)

# solve model
t_eval = np.linspace(0, 3800, 1000)
solver = pybamm.CasadiSolver(mode="fast", atol=1e-6, rtol=1e-3)
t_eval = np.linspace(0, 7200, 1000)
solver = pybamm.CasadiSolver(mode="safe", atol=1e-6, rtol=1e-3)
solution = solver.solve(model, t_eval)

# plot
plot = pybamm.QuickPlot(
solution,
[
"Negative particle surface concentration [mol.m-3]",
"Working particle concentration [mol.m-3]",
"Electrolyte concentration [mol.m-3]",
"Positive particle surface concentration [mol.m-3]",
"Current [A]",
"Negative electrode potential [V]",
"Working electrode potential [V]",
"Electrolyte potential [V]",
"Positive electrode potential [V]",
"Terminal voltage [V]",
"Total electrolyte concentration",
"Total lithium in working electrode [mol]",
"Working electrode open circuit potential [V]",
["Terminal voltage [V]", "Voltage drop in the cell [V]"],
],
time_unit="seconds",
spatial_unit="um",
Expand Down
2 changes: 2 additions & 0 deletions pybamm/expression_tree/symbol.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ def domain_size(domain):
"negative electrode": 11,
"separator": 13,
"positive electrode": 17,
"working electrode": 19,
"working particle": 23,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to check why this was necessary but not urgent

Copy link
Sponsor Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this has to do because the separator and current collector were defined in fixed_domain_sizes but the new domains weren't, so when they interact it breaks down...

Also, random question related to that. When we get the size of a variable defined in a domain in fixed_domain_sizes, why do we take the sum and not the product? I thought the idea of assigning prime numbers to the domains was to get unique signatures for each combination.

}
if isinstance(domain, str):
domain = [domain]
Expand Down
9 changes: 7 additions & 2 deletions pybamm/expression_tree/unary_operators.py
Original file line number Diff line number Diff line change
Expand Up @@ -1286,22 +1286,27 @@ def r_average(symbol):
raise ValueError("Can't take the r-average of a symbol that evaluates on edges")
# Otherwise, if symbol doesn't have a particle domain,
# its r-averaged value is itself
elif symbol.domain not in [["positive particle"], ["negative particle"]]:
elif symbol.domain not in [
["positive particle"],
["negative particle"],
["working particle"],
]:
new_symbol = symbol.new_copy()
new_symbol.parent = None
return new_symbol
# If symbol is a secondary broadcast onto "negative electrode" or
# "positive electrode", take the r-average of the child then broadcast back
elif isinstance(symbol, pybamm.SecondaryBroadcast) and symbol.domains[
"secondary"
] in [["positive electrode"], ["negative electrode"]]:
] in [["positive electrode"], ["negative electrode"], ["working electrode"]]:
child = symbol.orphans[0]
child_av = pybamm.r_average(child)
return pybamm.PrimaryBroadcast(child_av, symbol.domains["secondary"])
# If symbol is a Broadcast onto a particle domain, its average value is its child
elif isinstance(symbol, pybamm.PrimaryBroadcast) and symbol.domain in [
["positive particle"],
["negative particle"],
["working particle"],
]:
return symbol.orphans[0]
else:
Expand Down
88 changes: 88 additions & 0 deletions pybamm/geometry/half_cell_geometry.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#
# Function to create battery geometries
#
import pybamm
from pybamm.geometry import half_cell_spatial_vars


def half_cell_geometry(
include_particles=True, current_collector_dimension=0, working_electrode="positive"
):
"""
A convenience function to create battery geometries.

Parameters
----------
include_particles : bool
Whether to include particle domains
current_collector_dimensions : int, default
The dimensions of the current collector. Should be 0 (default), 1 or 2
current_collector_dimensions : string
The electrode taking as working electrode. Should be "positive" or "negative"

Returns
-------
:class:`pybamm.Geometry`
A geometry class for the battery

"""
var = half_cell_spatial_vars
geo = pybamm.geometric_parameters
if working_electrode == "positive":
l_w = geo.l_p
elif working_electrode == "negative":
l_w = geo.l_n
else:
raise ValueError(
"The option 'working_electrode' should be either 'positive'"
" or 'negative'"
)
l_Li = geo.l_Li
l_s = geo.l_s

geometry = {
"lithium counter electrode": {var.x_Li: {"min": 0, "max": l_Li}},
"separator": {var.x_s: {"min": l_Li, "max": l_Li + l_s}},
"working electrode": {var.x_w: {"min": l_Li + l_s, "max": l_Li + l_s + l_w}},
}
# Add particle domains
if include_particles is True:
geometry.update(
{"working particle": {var.r_w: {"min": 0, "max": 1}}}
)

if current_collector_dimension == 0:
geometry["current collector"] = {var.z: {"position": 1}}
elif current_collector_dimension == 1:
geometry["current collector"] = {
var.z: {"min": 0, "max": 1},
"tabs": {
"negative": {"z_centre": geo.centre_z_tab_n},
"positive": {"z_centre": geo.centre_z_tab_p},
},
}
elif current_collector_dimension == 2:
geometry["current collector"] = {
var.y: {"min": 0, "max": geo.l_y},
var.z: {"min": 0, "max": geo.l_z},
"tabs": {
"negative": {
"y_centre": geo.centre_y_tab_n,
"z_centre": geo.centre_z_tab_n,
"width": geo.l_tab_n,
},
"positive": {
"y_centre": geo.centre_y_tab_p,
"z_centre": geo.centre_z_tab_p,
"width": geo.l_tab_p,
},
},
}
else:
raise pybamm.GeometryError(
"Invalid current collector dimension '{}' (should be 0, 1 or 2)".format(
current_collector_dimension
)
)

return pybamm.Geometry(geometry)
85 changes: 85 additions & 0 deletions pybamm/geometry/half_cell_spatial_vars.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import pybamm

whole_cell = ["separator", "working electrode"]

# Domains at cell centres
x_Li = pybamm.SpatialVariable(
"x_Li",
domain=["lithium counter electrode"],
auxiliary_domains={"secondary": "current collector"},
coord_sys="cartesian",
)
x_s = pybamm.SpatialVariable(
"x_s",
domain=["separator"],
auxiliary_domains={"secondary": "current collector"},
coord_sys="cartesian",
)
x_w = pybamm.SpatialVariable(
"x_w",
domain=["working electrode"],
auxiliary_domains={"secondary": "current collector"},
coord_sys="cartesian",
)
x = pybamm.SpatialVariable(
"x",
domain=whole_cell,
auxiliary_domains={"secondary": "current collector"},
coord_sys="cartesian",
)

y = pybamm.SpatialVariable("y", domain="current collector", coord_sys="cartesian")
z = pybamm.SpatialVariable("z", domain="current collector", coord_sys="cartesian")

r_w = pybamm.SpatialVariable(
"r_w",
domain=["working particle"],
auxiliary_domains={
"secondary": "working electrode",
"tertiary": "current collector",
},
coord_sys="spherical polar",
)

# Domains at cell edges
x_Li_edge = pybamm.SpatialVariableEdge(
"x_Li",
domain=["lithium counter electrode"],
auxiliary_domains={"secondary": "current collector"},
coord_sys="cartesian",
)
x_s_edge = pybamm.SpatialVariableEdge(
"x_s",
domain=["separator"],
auxiliary_domains={"secondary": "current collector"},
coord_sys="cartesian",
)
x_w_edge = pybamm.SpatialVariableEdge(
"x_w",
domain=["working electrode"],
auxiliary_domains={"secondary": "current collector"},
coord_sys="cartesian",
)
x_edge = pybamm.SpatialVariableEdge(
"x",
domain=whole_cell,
auxiliary_domains={"secondary": "current collector"},
coord_sys="cartesian",
)

y_edge = pybamm.SpatialVariableEdge(
"y", domain="current collector", coord_sys="cartesian"
)
z_edge = pybamm.SpatialVariableEdge(
"z", domain="current collector", coord_sys="cartesian"
)

r_w_edge = pybamm.SpatialVariableEdge(
"r_w",
domain=["working particle"],
auxiliary_domains={
"secondary": "working electrode",
"tertiary": "current collector",
},
coord_sys="spherical polar",
)
Loading