Skip to content

Commit d685c38

Browse files
Merge branch 'develop' into fix-default-imports
2 parents 2213407 + bfddc83 commit d685c38

File tree

14 files changed

+110
-113
lines changed

14 files changed

+110
-113
lines changed

.github/release_workflow.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Release workflow
22

3-
This file contains the workflow required to make a `PyBaMM` release on GitHub and PyPI by the maintainers.
3+
This file contains the workflow required to make a `PyBaMM` release on GitHub, PyPI, and conda-forge by the maintainers.
44

55
## rc0 releases (automated)
66

@@ -77,3 +77,5 @@ Some other essential things to check throughout the release process -
7777
git tag -f <tag_name> <commit_hash>
7878
git push -f <pybamm-team/PyBaMM_remote_name> <tag_name> # can only be carried out by the maintainers
7979
```
80+
- If changes are made to the API, console scripts, entry points, new optional dependencies are added, support for major Python versions is dropped or added, or core project information and metadata are modified at the time of the release, make sure to update the `meta.yaml` file in the `recipe/` folder of the [conda-forge/pybamm-feedstock](https://github.com/conda-forge/pybamm-feedstock) repository accordingly by following the instructions in the [conda-forge documentation](https://conda-forge.org/docs/maintainer/updating_pkgs.html#updating-the-feedstock-repository) and re-rendering the recipe
81+
- The conda-forge release workflow will automatically be triggered following a stable PyPI release, and the aforementioned updates should be carried out directly in the main repository by pushing changes to the automated PR created by the conda-forge-bot. A manual PR can also be created if the updates are not included in the automated PR for some reason. This manual PR **must** bump the build number in `meta.yaml` and **must** be from a personal fork of the repository.

.github/workflows/test_on_push.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ jobs:
5050

5151
# Install and cache apt packages
5252
- name: Install Linux system dependencies
53-
uses: awalsh128/[email protected].0
53+
uses: awalsh128/[email protected].1
5454
if: matrix.os == 'ubuntu-latest'
5555
with:
5656
packages: gfortran gcc graphviz pandoc
@@ -130,7 +130,7 @@ jobs:
130130

131131
# Install and cache apt packages
132132
- name: Install Linux system dependencies
133-
uses: awalsh128/[email protected].0
133+
uses: awalsh128/[email protected].1
134134
with:
135135
packages: gfortran gcc graphviz pandoc
136136
execute_install_scripts: true
@@ -193,7 +193,7 @@ jobs:
193193

194194
# Install and cache apt packages
195195
- name: Install Linux system dependencies
196-
uses: awalsh128/[email protected].0
196+
uses: awalsh128/[email protected].1
197197
if: matrix.os == 'ubuntu-latest'
198198
with:
199199
packages: gfortran gcc graphviz pandoc
@@ -274,7 +274,7 @@ jobs:
274274

275275
# Install and cache apt packages
276276
- name: Install Linux system dependencies
277-
uses: awalsh128/[email protected].0
277+
uses: awalsh128/[email protected].1
278278
with:
279279
packages: gfortran gcc graphviz pandoc
280280
execute_install_scripts: true
@@ -319,7 +319,7 @@ jobs:
319319

320320
# Install and cache apt packages
321321
- name: Install Linux system dependencies
322-
uses: awalsh128/[email protected].0
322+
uses: awalsh128/[email protected].1
323323
with:
324324
packages: gfortran gcc graphviz pandoc
325325
execute_install_scripts: true
@@ -377,7 +377,7 @@ jobs:
377377

378378
# Install and cache apt packages
379379
- name: Install Linux system dependencies
380-
uses: awalsh128/[email protected].0
380+
uses: awalsh128/[email protected].1
381381
with:
382382
packages: gfortran gcc graphviz
383383
execute_install_scripts: true

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ ci:
44

55
repos:
66
- repo: https://github.com/astral-sh/ruff-pre-commit
7-
rev: "v0.1.3"
7+
rev: "v0.1.4"
88
hooks:
99
- id: ruff
1010
args: [--fix, --show-fixes]

docs/source/examples/notebooks/models/lithium-plating.ipynb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
"%pip install \"pybamm[plot,cite]\" -q # install PyBaMM if it is not installed\n",
3030
"import pybamm\n",
3131
"import os\n",
32-
"import matplotlib.pyplot as plt\n",
3332
"os.chdir(pybamm.__path__[0]+'/..')"
3433
]
3534
},

docs/source/examples/notebooks/models/pouch-cell-model.ipynb

Lines changed: 8 additions & 4 deletions
Large diffs are not rendered by default.

pybamm/expression_tree/binary_operators.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@
1414
def _preprocess_binary(left, right):
1515
if isinstance(left, numbers.Number):
1616
left = pybamm.Scalar(left)
17-
if isinstance(right, numbers.Number):
18-
right = pybamm.Scalar(right)
1917
elif isinstance(left, np.ndarray):
2018
if left.ndim > 1:
2119
raise ValueError("left must be a 1D array")
2220
left = pybamm.Vector(left)
21+
if isinstance(right, numbers.Number):
22+
right = pybamm.Scalar(right)
2323
elif isinstance(right, np.ndarray):
2424
if right.ndim > 1:
2525
raise ValueError("right must be a 1D array")

pybamm/expression_tree/broadcasts.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -546,8 +546,10 @@ def full_like(symbols, fill_value):
546546
return array_type(entries, domains=sum_symbol.domains)
547547

548548
except NotImplementedError:
549-
if sum_symbol.shape_for_testing == (1, 1) or sum_symbol.shape_for_testing == (
550-
1,
549+
if (
550+
sum_symbol.shape_for_testing == (1, 1)
551+
or sum_symbol.shape_for_testing == (1,)
552+
or sum_symbol.domain == []
551553
):
552554
return pybamm.Scalar(fill_value)
553555
if sum_symbol.evaluates_on_edges("primary"):

pybamm/models/full_battery_models/lithium_ion/electrode_soh.py

Lines changed: 26 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -410,10 +410,7 @@ def solve(self, inputs):
410410
# Calculate theoretical energy
411411
# TODO: energy calc for MSMR
412412
if self.options["open-circuit potential"] != "MSMR":
413-
energy = pybamm.lithium_ion.electrode_soh.theoretical_energy_integral(
414-
self.parameter_values,
415-
sol_dict,
416-
)
413+
energy = self.theoretical_energy_integral(sol_dict)
417414
sol_dict.update({"Maximum theoretical energy [W.h]": energy})
418415
return sol_dict
419416

@@ -829,6 +826,27 @@ def get_min_max_ocps(self):
829826
sol = self.solve(inputs)
830827
return [sol["Un(x_0)"], sol["Un(x_100)"], sol["Up(y_100)"], sol["Up(y_0)"]]
831828

829+
def theoretical_energy_integral(self, inputs, points=1000):
830+
x_0 = inputs["x_0"]
831+
y_0 = inputs["y_0"]
832+
x_100 = inputs["x_100"]
833+
y_100 = inputs["y_100"]
834+
Q_p = inputs["Q_p"]
835+
x_vals = np.linspace(x_100, x_0, num=points)
836+
y_vals = np.linspace(y_100, y_0, num=points)
837+
# Calculate OCV at each stoichiometry
838+
param = self.param
839+
T = param.T_amb_av(0)
840+
Vs = self.parameter_values.evaluate(
841+
param.p.prim.U(y_vals, T) - param.n.prim.U(x_vals, T)
842+
).flatten()
843+
# Calculate dQ
844+
Q = Q_p * (y_0 - y_100)
845+
dQ = Q / (points - 1)
846+
# Integrate and convert to W-h
847+
E = np.trapz(Vs, dx=dQ)
848+
return E
849+
832850

833851
def get_initial_stoichiometries(
834852
initial_value,
@@ -972,7 +990,7 @@ def get_min_max_ocps(
972990
return esoh_solver.get_min_max_ocps()
973991

974992

975-
def theoretical_energy_integral(parameter_values, inputs, points=100):
993+
def theoretical_energy_integral(parameter_values, param, inputs, points=100):
976994
"""
977995
Calculate maximum energy possible from a cell given OCV, initial soc, and final soc
978996
given voltage limits, open-circuit potentials, etc defined by parameter_values
@@ -991,30 +1009,8 @@ def theoretical_energy_integral(parameter_values, inputs, points=100):
9911009
E
9921010
The total energy of the cell in Wh
9931011
"""
994-
x_0 = inputs["x_0"]
995-
y_0 = inputs["y_0"]
996-
x_100 = inputs["x_100"]
997-
y_100 = inputs["y_100"]
998-
Q_p = inputs["Q_p"]
999-
x_vals = np.linspace(x_100, x_0, num=points)
1000-
y_vals = np.linspace(y_100, y_0, num=points)
1001-
# Calculate OCV at each stoichiometry
1002-
param = pybamm.LithiumIonParameters()
1003-
y = pybamm.standard_spatial_vars.y
1004-
z = pybamm.standard_spatial_vars.z
1005-
T = pybamm.yz_average(param.T_amb(y, z, 0))
1006-
Vs = np.empty(x_vals.shape)
1007-
for i in range(x_vals.size):
1008-
Vs[i] = (
1009-
parameter_values.evaluate(param.p.prim.U(y_vals[i], T)).item()
1010-
- parameter_values.evaluate(param.n.prim.U(x_vals[i], T)).item()
1011-
)
1012-
# Calculate dQ
1013-
Q = Q_p * (y_0 - y_100)
1014-
dQ = Q / (points - 1)
1015-
# Integrate and convert to W-h
1016-
E = np.trapz(Vs, dx=dQ)
1017-
return E
1012+
esoh_solver = ElectrodeSOHSolver(parameter_values, param)
1013+
return esoh_solver.theoretical_energy_integral(inputs, points=points)
10181014

10191015

10201016
def calculate_theoretical_energy(
@@ -1045,6 +1041,7 @@ def calculate_theoretical_energy(
10451041
Q_p = parameter_values.evaluate(pybamm.LithiumIonParameters().p.prim.Q_init)
10461042
E = theoretical_energy_integral(
10471043
parameter_values,
1044+
pybamm.LithiumIonParameters(),
10481045
{"x_100": x_100, "x_0": x_0, "y_100": y_100, "y_0": y_0, "Q_p": Q_p},
10491046
points=points,
10501047
)

pybamm/models/submodels/thermal/lumped.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,9 @@ def set_rhs(self, variables):
5656
# Newton cooling, accounting for surface area to volume ratio
5757
cell_surface_area = self.param.A_cooling
5858
cell_volume = self.param.V_cell
59-
total_cooling_coefficient = (
60-
-self.param.h_total * cell_surface_area / cell_volume
59+
Q_cool_vol_av = (
60+
-self.param.h_total * (T_vol_av - T_amb) * cell_surface_area / cell_volume
6161
)
62-
Q_cool_vol_av = total_cooling_coefficient * (T_vol_av - T_amb)
6362

6463
self.rhs = {
6564
T_vol_av: (Q_vol_av + Q_cool_vol_av) / self.param.rho_c_p_eff(T_vol_av)

pybamm/models/submodels/thermal/pouch_cell/pouch_cell_1D_current_collectors.py

Lines changed: 28 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -58,33 +58,29 @@ def set_rhs(self, variables):
5858
y = pybamm.standard_spatial_vars.y
5959
z = pybamm.standard_spatial_vars.z
6060

61-
# Account for surface area to volume ratio of pouch cell in surface and side
62-
# cooling terms
63-
cell_volume = self.param.L * self.param.L_y * self.param.L_z
64-
61+
# Calculate cooling, accounting for surface area to volume ratio of pouch cell
62+
edge_area = self.param.L_z * self.param.L
6563
yz_surface_area = self.param.L_y * self.param.L_z
66-
yz_surface_cooling_coefficient = (
64+
cell_volume = self.param.L * self.param.L_y * self.param.L_z
65+
Q_yz_surface = (
6766
-(self.param.n.h_cc(y, z) + self.param.p.h_cc(y, z))
67+
* (T_av - T_amb)
6868
* yz_surface_area
6969
/ cell_volume
7070
)
71-
72-
side_edge_area = self.param.L_z * self.param.L
73-
side_edge_cooling_coefficient = (
71+
Q_edge = (
7472
-(self.param.h_edge(0, z) + self.param.h_edge(self.param.L_y, z))
75-
* side_edge_area
73+
* (T_av - T_amb)
74+
* edge_area
7675
/ cell_volume
7776
)
78-
79-
total_cooling_coefficient = (
80-
yz_surface_cooling_coefficient + side_edge_cooling_coefficient
81-
)
77+
Q_cool_total = Q_yz_surface + Q_edge
8278

8379
self.rhs = {
8480
T_av: (
8581
pybamm.div(self.param.lambda_eff(T_av) * pybamm.grad(T_av))
8682
+ Q_av
87-
+ total_cooling_coefficient * (T_av - T_amb)
83+
+ Q_cool_total
8884
)
8985
/ self.param.rho_c_p_eff(T_av)
9086
}
@@ -94,7 +90,7 @@ def set_boundary_conditions(self, variables):
9490
T_amb = variables["Ambient temperature [K]"]
9591
T_av = variables["X-averaged cell temperature [K]"]
9692

97-
# find tab locations (top vs bottom)
93+
# Find tab locations (top vs bottom)
9894
L_y = param.L_y
9995
L_z = param.L_z
10096
neg_tab_z = param.n.centre_z_tab
@@ -104,11 +100,10 @@ def set_boundary_conditions(self, variables):
104100
pos_tab_top_bool = pybamm.Equality(pos_tab_z, L_z)
105101
pos_tab_bottom_bool = pybamm.Equality(pos_tab_z, 0)
106102

107-
# calculate tab vs non-tab area on top and bottom
103+
# Calculate tab vs non-tab area on top and bottom
108104
neg_tab_area = param.n.L_tab * param.n.L_cc
109105
pos_tab_area = param.p.L_tab * param.p.L_cc
110106
total_area = param.L * param.L_y
111-
112107
non_tab_top_area = (
113108
total_area
114109
- neg_tab_area * neg_tab_top_bool
@@ -120,18 +115,22 @@ def set_boundary_conditions(self, variables):
120115
- pos_tab_area * pos_tab_bottom_bool
121116
)
122117

123-
# calculate effective cooling coefficients
118+
# Calculate heat fluxes weighted by area
124119
# Note: can't do y-average of h_edge here since y isn't meshed. Evaluate at
125120
# midpoint.
126-
top_cooling_coefficient = (
127-
param.n.h_tab * neg_tab_area * neg_tab_top_bool
128-
+ param.p.h_tab * pos_tab_area * pos_tab_top_bool
129-
+ param.h_edge(L_y / 2, L_z) * non_tab_top_area
121+
q_tab_n = -param.n.h_tab * (T_av - T_amb)
122+
q_tab_p = -param.p.h_tab * (T_av - T_amb)
123+
q_edge_top = -param.h_edge(L_y / 2, L_z) * (T_av - T_amb)
124+
q_edge_bottom = -param.h_edge(L_y / 2, 0) * (T_av - T_amb)
125+
q_top = (
126+
q_tab_n * neg_tab_area * neg_tab_top_bool
127+
+ q_tab_p * pos_tab_area * pos_tab_top_bool
128+
+ q_edge_top * non_tab_top_area
130129
) / total_area
131-
bottom_cooling_coefficient = (
132-
param.n.h_tab * neg_tab_area * neg_tab_bottom_bool
133-
+ param.p.h_tab * pos_tab_area * pos_tab_bottom_bool
134-
+ param.h_edge(L_y / 2, 0) * non_tab_bottom_area
130+
q_bottom = (
131+
q_tab_n * neg_tab_area * neg_tab_bottom_bool
132+
+ q_tab_p * pos_tab_area * pos_tab_bottom_bool
133+
+ q_edge_bottom * non_tab_bottom_area
135134
) / total_area
136135

137136
# just use left and right for clarity
@@ -141,21 +140,14 @@ def set_boundary_conditions(self, variables):
141140
self.boundary_conditions = {
142141
T_av: {
143142
"left": (
144-
pybamm.boundary_value(
145-
bottom_cooling_coefficient * (T_av - T_amb),
146-
"left",
147-
)
148-
/ pybamm.boundary_value(lambda_eff, "left"),
143+
pybamm.boundary_value(-q_bottom / lambda_eff, "left"),
149144
"Neumann",
150145
),
151146
"right": (
152-
pybamm.boundary_value(
153-
-top_cooling_coefficient * (T_av - T_amb), "right"
154-
)
155-
/ pybamm.boundary_value(lambda_eff, "right"),
147+
pybamm.boundary_value(q_top / lambda_eff, "right"),
156148
"Neumann",
157149
),
158-
}
150+
},
159151
}
160152

161153
def set_initial_conditions(self, variables):

0 commit comments

Comments
 (0)