Skip to content

Commit

Permalink
pybamm-team#3321 move x-full inside pouch folder
Browse files Browse the repository at this point in the history
  • Loading branch information
rtimms committed Aug 8, 2023
1 parent 261aa28 commit 5b8eb25
Show file tree
Hide file tree
Showing 7 changed files with 70 additions and 41 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

## Features

- The parameter "Ambient temperature can now be given as a function of position `(y,z)` and time `t`. The heat transfer coefficient parameters can also depend on `(y,z)`.
- Numpy functions now work with PyBaMM symbols (e.g. `np.exp(pybamm.Symbol("a"))` returns `pybamm.Exp(pybamm.Symbol("a"))`). This means that parameter functions can be specified using numpy functions instead of pybamm functions. Additionally, combining numpy arrays with pybamm objects now works (the numpy array is converted to a pybamm array) ([#3205](https://github.com/pybamm-team/PyBaMM/pull/3205))

## Bug fixes

- The `OneDimensionalX` thermal model has been updated to account for edge/tab cooling and account for the current collector volumetric heat capacity. It now gives the correct behaviour compared with a lumped model with the correct total heat transfer coefficient and surface area for cooling. ([#3042](https://github.com/pybamm-team/PyBaMM/pull/3042))
- Fixed a bug where the "basic" lithium-ion models gave incorrect results when using nonlinear particle diffusivity ([#3207](https://github.com/pybamm-team/PyBaMM/pull/3207))
- Particle size distributions now work with SPMe and NewmanTobias models ([#3207](https://github.com/pybamm-team/PyBaMM/pull/3207))
- Fix to simulate c_rate steps with drive cycles ([#3186](https://github.com/pybamm-team/PyBaMM/pull/3186))
Expand All @@ -16,6 +18,8 @@

## Breaking changes

- The class `pybamm.thermal.OneDimensionalX` has been moved to `pybamm.thermal.pouch_cell.OneDimensionalX` to reflect the fact that the model formulation implicitly assumes a pouch cell geometry.
- The "lumped" thermal option now always used the parameters "Cell cooling surface area [m2]", "Cell volume [m3]" and "Total heat transfer coefficient [W.m-2.K-1]" to compute the cell cooling regardless of the chosen "cell geometry" option. The user must now specify the correct values for these parameters instead of them being calculated based on e.g. a pouch cell.
- Added option to use an empirical hysteresis model for the diffusivity and exchange-current density ([#3194](https://github.com/pybamm-team/PyBaMM/pull/3194))
- Double-layer capacity can now be provided as a function of temperature ([#3174](https://github.com/pybamm-team/PyBaMM/pull/3174))
- `pybamm_install_jax` is deprecated. It is now replaced with `pip install pybamm[jax]` ([#3163](https://github.com/pybamm-team/PyBaMM/pull/3163))
Expand Down
86 changes: 54 additions & 32 deletions docs/source/examples/notebooks/models/thermal-models.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
"source": [
"# Thermal models\n",
"\n",
"There are a number of thermal submodels available in PyBaMM. In this notebook we give details of each of the models, and highlight any relevant parameters. At present PyBaMM includes a lumped thermal model, a 1D thermal model which accounts for the through-cell variation in temperature, and a 2D pouch cell model which assumed the temperature is uniform through the thickness of the pouch, but accounts for variations in temperature in the remaining two dimensions. Here we give the governing equations for each model. \n",
"There are a number of thermal submodels available in PyBaMM. In this notebook we give details of each of the models, and highlight any relevant parameters. At present PyBaMM includes an isothermal and a lumped thermal model, both of which can be used with any cell geometry, as well as a 1D thermal model which accounts for the through-cell variation in temperature in a pouch cell, and \"1+1D\" and \"2+1D\" pouch cell models which assumed the temperature is uniform through the thickness of the pouch, but accounts for variations in temperature in the remaining dimensions. Here we give the governing equations for each model (except the isothermal model, which just sets the temperature to be equal to to the parameter \"Ambient temperature [K]\"). \n",
"\n",
"A more comprehensive review of the pouch cell models can be found in references [4] and [6] at the end of this notebook."
"A more comprehensive review of the pouch cell models, including how to properly compute the effective cooling terms, can be found in references [4] and [6] at the end of this notebook."
]
},
{
Expand Down Expand Up @@ -75,8 +75,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"### \"lumped\" option\n",
"This option allows any electrochmical model to be solved, coupled to a lumped thermal model that can be used to model any aribitrary geometry. The user may specify the total heat transfer coefficient $h$, surface area for cooling $A$, and cell volume $V$. The relevant parameters are: \n",
"The relevant parameters to specify the cooling conditions are: \n",
"\n",
"\"Total heat transfer coefficient [W.m-2.K-1]\" \n",
"\"Cell cooling surface area [m2]\" \n",
Expand All @@ -102,11 +101,19 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"## 1D (through-cell) model\n",
"## Pouch cell models"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"### 1D (through-cell) model\n",
"\n",
"The 1D model solves for $T(x,t)$, capturing variations through the thickness of the cell, but ignoring variations in the other dimensions. The temperature is found as the solution of a partial differential equation, given here in dimensional terms\n",
"\n",
"$$\\rho_k c_{p,k} \\frac{\\partial T}{\\partial t} = \\lambda_k \\nabla^2 T + Q(x,t)$$\n",
"$$\\rho_k c_{p,k} \\frac{\\partial T}{\\partial t} = \\lambda_k \\nabla^2 T + Q(x,t) - Q_{cool}(x,t)$$\n",
"\n",
"with boundary conditions \n",
"\n",
Expand All @@ -116,14 +123,21 @@
"\n",
"$$ T\\big|_{t=0} = T_0.$$\n",
"\n",
"Here $\\lambda_k$ is the thermal conductivity of component $k$, and the heat transfer coefficients $h_{cn}$ and $h_{cp}$ correspond to heat transfer at the large surface of the pouch on the side of the negative current collector, heat transfer at the large surface of the pouch on the side of the positive current collector, respectively. The heat source term $Q$ is as described in the section on lumped models. Note: the 1D model neglects any cooling from the tabs or edges of the cell -- it assumes a pouch cell geometry and _only_ accounts for cooling from the two large surfaces of the pouch. \n",
"Here $\\lambda_k$ is the thermal conductivity of component $k$, and the heat transfer coefficients $h_{cn}$ and $h_{cp}$ correspond to heat transfer at the large surface of the pouch on the side of the negative current collector, heat transfer at the large surface of the pouch on the side of the positive current collector, respectively. The heat source term $Q$ is as described in the section on lumped models. The term $Q_cool$ accounts for additional heat losses due to heat transfer at the sides of the pouch, as well as the tabs. This term is computed automatically by PyBaMM based on the cell geometry and heat transfer coefficients on the edges and tabs of the cell.\n",
"\n",
"The relevant heat transfer parameters are:\n",
"\"Negative current collector surface heat transfer coefficient [W.m-2.K-1]\"\n",
"\"Positive current collector surface heat transfer coefficient [W.m-2.K-1]\"\n",
"\"Negative tab heat transfer coefficient [W.m-2.K-1]\"\n",
"\"Positive tab heat transfer coefficient [W.m-2.K-1]\"\n",
"\"Edge heat transfer coefficient [W.m-2.K-1]\"\n",
"\n",
"The 1D model is termed \"x-full\" (since it fully accounts for variation in the x direction) and can be selected as follows\n"
]
},
{
"cell_type": "code",
"execution_count": 5,
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
Expand All @@ -136,9 +150,9 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"# Pouch cell models\n",
"## Higher dimensional pouch cell models\n",
"\n",
"The pouch cell thermal models ignore any variation in temperature through the thickness of the cell (x direction), and solve for $T(y,z,t)$. The temperature is found as the solution of a partial differential equation, given here in dimensional terms,\n",
"These pouch cell thermal models ignore any variation in temperature through the thickness of the cell (x direction), and solve for $T(y,z,t)$. It is therefore referred to as an \"x-lumped\" model. The temperature is found as the solution of a partial differential equation, given here in dimensional terms,\n",
"\n",
"$$\n",
"\\rho_{eff} \\frac{\\partial T}{\\partial t} = \\lambda_{eff} \\nabla_\\perp^2T + \\bar{Q} - \\frac{(h_{cn}+h_{cp})A}{V}(T-T_{\\infty}),\n",
Expand Down Expand Up @@ -172,12 +186,28 @@
"\n",
"The heat transfer coefficients $h_{cn}$, $h_{cp}$ and $h_{egde}$ correspond to heat transfer at the large surface of the pouch on the side of the negative current collector, heat transfer at the large surface of the pouch on the side of the positive current collector, and heat transfer at the remaining, respectively.\n",
"\n",
"As with the \"x-lumped\" option, the relevant heat transfer parameters are:\n",
"The relevant heat transfer parameters are:\n",
"\"Negative current collector surface heat transfer coefficient [W.m-2.K-1]\"\n",
"\"Positive current collector surface heat transfer coefficient [W.m-2.K-1]\"\n",
"\"Negative tab heat transfer coefficient [W.m-2.K-1]\"\n",
"\"Positive tab heat transfer coefficient [W.m-2.K-1]\"\n",
"\"Edge heat transfer coefficient [W.m-2.K-1]\"\n"
"\"Edge heat transfer coefficient [W.m-2.K-1]\"\n",
"\n",
"The \"2+1D\" model can be selected as follows"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"options = {\n",
" \"current collector\": \"potential pair\",\n",
" \"dimensionality\": 2,\n",
" \"thermal\": \"x-lumped\",\n",
"}\n",
"model = pybamm.lithium_ion.DFN(options)"
]
},
{
Expand All @@ -198,7 +228,7 @@
},
{
"cell_type": "code",
"execution_count": 13,
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
Expand All @@ -221,7 +251,7 @@
},
{
"cell_type": "code",
"execution_count": 14,
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
Expand All @@ -238,7 +268,7 @@
},
{
"cell_type": "code",
"execution_count": 15,
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
Expand Down Expand Up @@ -270,7 +300,7 @@
},
{
"cell_type": "code",
"execution_count": 16,
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
Expand All @@ -294,26 +324,18 @@
},
{
"cell_type": "code",
"execution_count": 20,
"execution_count": 10,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"hi\n",
"hi\n"
]
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "1169e50029dc4054a65d583321a6a919",
"model_id": "97a1370f6f8745b0a4b2a7bb4df5b477",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"interactive(children=(FloatSlider(value=0.0, description='t', max=1154.8765298002877, step=11.548765298002877)…"
"interactive(children=(FloatSlider(value=0.0, description='t', max=1154.7667871396477, step=11.547667871396477)…"
]
},
"metadata": {},
Expand All @@ -322,12 +344,12 @@
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "45569a0e5cca46fcb25956cd0ca8673d",
"model_id": "fb646d540c774a10af2ee25e79251283",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"interactive(children=(FloatSlider(value=0.0, description='t', max=1154.8765298002877, step=11.548765298002877)…"
"interactive(children=(FloatSlider(value=0.0, description='t', max=1154.7667871396477, step=11.547667871396477)…"
]
},
"metadata": {},
Expand All @@ -336,10 +358,10 @@
{
"data": {
"text/plain": [
"<pybamm.plotting.quick_plot.QuickPlot at 0x17996ab80>"
"<pybamm.plotting.quick_plot.QuickPlot at 0x14e1456d0>"
]
},
"execution_count": 20,
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
Expand Down Expand Up @@ -387,7 +409,7 @@
},
{
"cell_type": "code",
"execution_count": 12,
"execution_count": 11,
"metadata": {},
"outputs": [
{
Expand Down
2 changes: 1 addition & 1 deletion pybamm/models/full_battery_models/base_battery_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -1061,7 +1061,7 @@ def set_thermal_submodel(self):
thermal_submodel = pybamm.thermal.pouch_cell.CurrentCollector2D
elif self.options["thermal"] == "x-full":
if self.options["dimensionality"] == 0:
thermal_submodel = pybamm.thermal.OneDimensionalX
thermal_submodel = pybamm.thermal.pouch_cell.OneDimensionalX

self.submodels["thermal"] = thermal_submodel(self.param, self.options)

Expand Down
1 change: 0 additions & 1 deletion pybamm/models/submodels/thermal/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from .base_thermal import BaseThermal
from .isothermal import Isothermal
from .lumped import Lumped
from .x_full import OneDimensionalX
from . import pouch_cell
1 change: 1 addition & 0 deletions pybamm/models/submodels/thermal/pouch_cell/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
from .x_full import OneDimensionalX
from .pouch_cell_1D_current_collectors import CurrentCollector1D
from .pouch_cell_2D_current_collectors import CurrentCollector2D
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#
import pybamm

from .base_thermal import BaseThermal
from ..base_thermal import BaseThermal


class OneDimensionalX(BaseThermal):
Expand Down Expand Up @@ -80,6 +80,8 @@ def set_rhs(self, variables):
Q_cn = variables["Negative current collector Ohmic heating [W.m-3]"]
Q_cp = variables["Positive current collector Ohmic heating [W.m-3]"]
T_amb = variables["Ambient temperature [K]"]
y = pybamm.standard_spatial_vars.y
z = pybamm.standard_spatial_vars.z

# Define volumetric heat capacity for electrode/separator/electrode sandwich
rho_c_p = pybamm.concatenation(
Expand All @@ -100,34 +102,35 @@ def set_rhs(self, variables):
L_z = self.param.L_z
L_cn = self.param.n.L_cc
L_cp = self.param.p.L_cc
h_cn = self.param.n.h_cc
h_cp = self.param.p.h_cc
h_cn = self.param.n.h_cc(y, z)
h_cp = self.param.p.h_cc(y, z)
lambda_n = self.param.n.lambda_(T_n)
lambda_p = self.param.p.lambda_(T_p)
h_edge = self.param.h_edge(y, z)
# Negative current collector
volume_cn = L_cn * L_y * L_z
negative_tab_area = self.param.n.L_tab * self.param.n.L_cc
edge_area_cn = 2 * (L_y + L_z) * L_cn - negative_tab_area
negative_tab_cooling_coefficient = (
-self.param.n.h_tab * negative_tab_area / volume_cn
)
edge_cooling_coefficient_cn = -self.param.h_edge * edge_area_cn / volume_cn
edge_cooling_coefficient_cn = -h_edge * edge_area_cn / volume_cn
cooling_coefficient_cn = (
negative_tab_cooling_coefficient + edge_cooling_coefficient_cn
)
# Electrode/separator/electrode sandwich
area_to_volume = (
2 * (self.param.L_y + self.param.L_z) / (self.param.L_y * self.param.L_z)
)
cooling_coefficient = -self.param.h_edge * area_to_volume
cooling_coefficient = -h_edge * area_to_volume
# Positive current collector
volume_cp = L_cp * L_y * L_z
positive_tab_area = self.param.p.L_tab * self.param.p.L_cc
edge_area_cp = 2 * (L_y + L_z) * L_cp - positive_tab_area
positive_tab_cooling_coefficient = (
-self.param.p.h_tab * positive_tab_area / volume_cp
)
edge_cooling_coefficient_cp = -self.param.h_edge * edge_area_cp / volume_cp
edge_cooling_coefficient_cp = -h_edge * edge_area_cp / volume_cp
cooling_coefficient_cp = (
positive_tab_cooling_coefficient + edge_cooling_coefficient_cp
)
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/test_citations.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ def test_timms_2021(self):

citations._reset()
self.assertNotIn("Timms2021", citations._papers_to_cite)
pybamm.thermal.OneDimensionalX(param=None)
pybamm.thermal.pouch_cell.OneDimensionalX(param=None)
self.assertIn("Timms2021", citations._papers_to_cite)
self.assertIn("Timms2021", citations._citation_tags.keys())

Expand Down

0 comments on commit 5b8eb25

Please sign in to comment.