From 152d28f962bd79e093c0f2c38dc80caea2c41dea Mon Sep 17 00:00:00 2001 From: Scott Marquis Date: Thu, 16 Apr 2020 17:36:07 +0100 Subject: [PATCH 01/15] #912 added cooling to lumped and 2D models --- examples/scripts/example.py | 51 +++++++++++++++++++ pybamm/models/submodels/thermal/lumped.py | 43 ++++++++++++++-- .../pouch_cell_2D_current_collectors.py | 48 ++++++++++++----- pybamm/models/submodels/thermal/x_full.py | 1 + pybamm/parameters/thermal_parameters.py | 23 ++++++--- 5 files changed, 144 insertions(+), 22 deletions(-) create mode 100644 examples/scripts/example.py diff --git a/examples/scripts/example.py b/examples/scripts/example.py new file mode 100644 index 0000000000..9b37e6a14c --- /dev/null +++ b/examples/scripts/example.py @@ -0,0 +1,51 @@ +import pybamm +import numpy as np +import matplotlib.pyplot as plt + + +options = { + "thermal": "x-lumped", + "current collector": "potential pair", + "dimensionality": 1, +} +model = pybamm.lithium_ion.DFN(options=options) + +var = pybamm.standard_spatial_vars +# var_pts = { +# var.x_n: 5, +# var.x_s: 5, +# var.x_p: 5, +# var.r_n: 5, +# var.r_p: 5, +# var.y: 5, +# var.z: 5, +# } + +var_pts = None + +solver = pybamm.CasadiSolver(mode="fast") +sim = pybamm.Simulation(model, var_pts=var_pts, solver=solver, C_rate=1) +sim.solve() + +t = sim.solution.t +l_y = sim.parameter_values.evaluate(pybamm.geometric_parameters.l_y) +x = np.linspace(0, 1, 19) +y = np.linspace(0, l_y, 20) +z = np.linspace(0, 1, 21) + +cell_temp = sim.solution["X-averaged cell temperature [K]"](t=t, y=y, z=z) +# cell_temp = sim.solution["Negative current collector potential [V]"](t=t, y=y, z=z) +# max_temp = np.max(np.max(cell_temp, axis=0), axis=0) +# min_temp = np.min(np.min(cell_temp, axis=0), axis=0) +max_temp = np.max(cell_temp, axis=0) +min_temp = np.min(cell_temp, axis=0) +delta_t = max_temp - min_temp + + +plt.plot(t, delta_t) +plt.show() + +plt.plot(t, max_temp) +plt.plot(t, min_temp) + +plt.show() diff --git a/pybamm/models/submodels/thermal/lumped.py b/pybamm/models/submodels/thermal/lumped.py index 3b4a63dc9e..78fe5e525c 100644 --- a/pybamm/models/submodels/thermal/lumped.py +++ b/pybamm/models/submodels/thermal/lumped.py @@ -53,12 +53,47 @@ def set_rhs(self, variables): # the choice of non-dimensionalisation. # TODO: allow for arbitrary surface area to volume ratio in order to model # different cell geometries (see #718) - A = self.param.l_y * self.param.l_z - V = self.param.l * self.param.l_y * self.param.l_z - cooling_coeff = -2 * self.param.h * A / V / (self.param.delta ** 2) + cell_volume = self.param.l * self.param.l_y * self.param.l_z + + yz_cell_surface_area = self.param.l_y * self.param.l_z + yz_surface_cooling_coefficient = ( + -(self.param.h_cn + self.param.h_cp) + * yz_cell_surface_area + / cell_volume + / (self.param.delta ** 2) + ) + + negative_tab_area = self.param.l_tab_n * self.param.l_cn + negative_tab_cooling_coefficient = ( + -self.param.h_tab_n * negative_tab_area / cell_volume / self.param.delta + ) + + positive_tab_area = self.param.l_tab_p * self.param.l_cp + positive_tab_cooling_coefficient = ( + -self.param.h_tab_p * positive_tab_area / cell_volume / self.param.delta + ) + + edge_area = ( + 2 * self.param.l_y * self.param.l + + 2 * self.param.l_z * self.param.l + - negative_tab_area + - positive_tab_area + ) + edge_cooling_coefficient = ( + -self.param.h_edge * edge_area / cell_volume / self.param.delta + ) + + total_cooling_coefficient = ( + yz_surface_cooling_coefficient + + negative_tab_cooling_coefficient + + positive_tab_cooling_coefficient + + edge_cooling_coefficient + ) self.rhs = { - T_vol_av: (self.param.B * Q_vol_av + cooling_coeff * (T_vol_av - T_amb)) + T_vol_av: ( + self.param.B * Q_vol_av + total_cooling_coefficient * (T_vol_av - T_amb) + ) / (self.param.C_th * self.param.rho) } diff --git a/pybamm/models/submodels/thermal/pouch_cell/pouch_cell_2D_current_collectors.py b/pybamm/models/submodels/thermal/pouch_cell/pouch_cell_2D_current_collectors.py index 8901318dc9..8ebcae121c 100644 --- a/pybamm/models/submodels/thermal/pouch_cell/pouch_cell_2D_current_collectors.py +++ b/pybamm/models/submodels/thermal/pouch_cell/pouch_cell_2D_current_collectors.py @@ -62,32 +62,56 @@ def set_rhs(self, variables): # non-dimensionalisation A = self.param.l_y * self.param.l_z V = self.param.l * self.param.l_y * self.param.l_z - cooling_coeff = -2 * self.param.h * A / V / (self.param.delta ** 2) + surface_cooling_coefficient = ( + -(self.param.h_cn + self.param.h_cp) * A / V / (self.param.delta ** 2) + ) # cooling on the y-z surfaces - # Add boundary source term which accounts for surface cooling around - # the edge of the domain in the weak formulation. - # TODO: update to allow different cooling conditions at the tabs + edge_cooling_coefficient = self.param.h_edge / self.param.delta + + # Governing equations contain: + # - source term for y-z surface cooling + # - boundary source term of edge cooling + # Boundary conditions contain: + # - Neumann condition for tab cooling self.rhs = { T_av: ( pybamm.laplacian(T_av) + self.param.B * pybamm.source(Q_av, T_av) - + cooling_coeff * pybamm.source(T_av - T_amb, T_av) - - (self.param.h / self.param.delta) + + surface_cooling_coefficient * pybamm.source(T_av - T_amb, T_av) + - edge_cooling_coefficient * pybamm.source(T_av - T_amb, T_av, boundary=True) ) / (self.param.C_th * self.param.rho) } + # TODO: Make h_edge a function of position to have bottom/top/side cooled cells. + def set_boundary_conditions(self, variables): T_av = variables["X-averaged cell temperature"] - # Dummy no flux boundary conditions since cooling at the the tabs is - # accounted for in the boundary source term in the weak form of the - # governing equation - # TODO: update to allow different cooling conditions at the tabs + T_amb = variables["Ambient temperature"] + + # Subtract the edge cooling from the tab portion so as to not double count + # Note: tab cooling is also only applied on the current collector hence + # the (l_cn / l) and (l_cp / l) prefactors. + # We also still have edge cooling on the region: x in (0, 1) + h_tab_n_corrected = ( + (self.param.l_cn / self.param.l) + * (self.param.h_tab_n - self.param.h_edge) + / self.param.delta + ) + h_tab_p_corrected = ( + (self.param.l_cp / self.param.l) + * (self.param.h_tab_p - self.param.h_edge) + / self.param.delta + ) + + T_av_n = pybamm.BoundaryValue(T_av, "negative tab") + T_av_p = pybamm.BoundaryValue(T_av, "positive tab") + self.boundary_conditions = { T_av: { - "negative tab": (pybamm.Scalar(0), "Neumann"), - "positive tab": (pybamm.Scalar(0), "Neumann"), + "negative tab": -(h_tab_n_corrected * (T_av_n - T_amb), "Neumann"), + "positive tab": -(h_tab_p_corrected * (T_av_p - T_amb), "Neumann"), } } diff --git a/pybamm/models/submodels/thermal/x_full.py b/pybamm/models/submodels/thermal/x_full.py index 22ebb8a745..2331a2de04 100644 --- a/pybamm/models/submodels/thermal/x_full.py +++ b/pybamm/models/submodels/thermal/x_full.py @@ -51,6 +51,7 @@ def set_rhs(self, variables): # Fourier's law for heat flux q = -self.param.lambda_k * pybamm.grad(T) + # N.B only y-z surface cooling is implemented for this model self.rhs = { T: (-pybamm.div(q) / self.param.delta ** 2 + self.param.B * Q) / (self.param.C_th * self.param.rho_k) diff --git a/pybamm/parameters/thermal_parameters.py b/pybamm/parameters/thermal_parameters.py index 76ce5e850d..2c3a45ba3c 100644 --- a/pybamm/parameters/thermal_parameters.py +++ b/pybamm/parameters/thermal_parameters.py @@ -55,13 +55,18 @@ ) / pybamm.geometric_parameters.L # Cooling coefficient -h_dim = pybamm.Parameter("Heat transfer coefficient [W.m-2.K-1]") +h_cn_dim = pybamm.Parameter( + "Negative current collector surface heat transfer coefficient [W.m-2.K-1]" +) +h_cp_dim = pybamm.Parameter( + "Positive current collector surface heat transfer coefficient [W.m-2.K-1]" +) +h_tab_n_dim = pybamm.Parameter("Negative tab heat transfer coefficient [W.m-2.K-1]") +h_tab_p_dim = pybamm.Parameter("Positive tab heat transfer coefficient [W.m-2.K-1]") +h_edge_dim = pybamm.Parameter("Edge heat transfer coefficient [W.m-2.K-1]") # Typical temperature rise -Phi_dim = pybamm.Scalar(1) # typical scale for voltage drop across cell (order 1V) -Delta_T = ( - pybamm.electrical_parameters.i_typ * Phi_dim / h_dim -) # computed from balance of typical cross-cell Ohmic heating with surface heat loss +Delta_T = pybamm.Scalar(1) # Initial temperature T_init_dim = pybamm.Parameter("Initial temperature [K]") @@ -99,7 +104,13 @@ Theta = Delta_T / T_ref -h = h_dim * pybamm.geometric_parameters.L_x / lambda_eff_dim + +h_edge = h_edge_dim * pybamm.geometric_parameters.L_x / lambda_eff_dim +h_tab_n = h_tab_n_dim * pybamm.geometric_parameters.L_x / lambda_eff_dim +h_tab_p = h_tab_p_dim * pybamm.geometric_parameters.L_x / lambda_eff_dim +h_cn = h_cn_dim * pybamm.geometric_parameters.L_x / lambda_eff_dim +h_cp = h_cp_dim * pybamm.geometric_parameters.L_x / lambda_eff_dim + T_init = (T_init_dim - T_ref) / Delta_T From ac3fc95ba281d84765a939d2d3429d170bf8f51d Mon Sep 17 00:00:00 2001 From: Scott Marquis Date: Fri, 17 Apr 2020 09:49:58 +0100 Subject: [PATCH 02/15] #912 added cooling to 1D current collector --- .../pouch_cell_1D_current_collectors.py | 60 +++++++++++++++---- .../pouch_cell_2D_current_collectors.py | 15 +++-- 2 files changed, 59 insertions(+), 16 deletions(-) diff --git a/pybamm/models/submodels/thermal/pouch_cell/pouch_cell_1D_current_collectors.py b/pybamm/models/submodels/thermal/pouch_cell/pouch_cell_1D_current_collectors.py index 1fb3a43529..eaf1394b32 100644 --- a/pybamm/models/submodels/thermal/pouch_cell/pouch_cell_1D_current_collectors.py +++ b/pybamm/models/submodels/thermal/pouch_cell/pouch_cell_1D_current_collectors.py @@ -60,15 +60,30 @@ def set_rhs(self, variables): # Account for surface area to volume ratio of pouch cell in cooling # coefficient. Note: the factor 1/delta^2 comes from the choice of # non-dimensionalisation - A = self.param.l_y * self.param.l_z - V = self.param.l * self.param.l_y * self.param.l_z - cooling_coeff = -2 * self.param.h * A / V / (self.param.delta ** 2) + cell_volume = self.param.l * self.param.l_y * self.param.l_z + + yz_surface_area = self.param.l_y * self.param.l_z + yz_surface_cooling_coefficient = ( + -(self.param.h_cn + self.param.h_cp) + * yz_surface_area + / cell_volume + / (self.param.delta ** 2) + ) + + side_edge_area = 2 * self.param.l_z * self.param.l + side_edge_cooling_coefficient = ( + -self.param.h_edge * side_edge_area / cell_volume / self.param.delta + ) + + total_cooling_coefficient = ( + yz_surface_cooling_coefficient + side_edge_cooling_coefficient + ) self.rhs = { T_av: ( pybamm.laplacian(T_av) + self.param.B * Q_av - + cooling_coeff * (T_av - T_amb) + + total_cooling_coefficient * (T_av - T_amb) ) / (self.param.C_th * self.param.rho) } @@ -79,18 +94,43 @@ def set_boundary_conditions(self, variables): T_av_left = pybamm.boundary_value(T_av, "negative tab") T_av_right = pybamm.boundary_value(T_av, "positive tab") - # Three boundary conditions here to handle the cases of both tabs at - # the same side (top or bottom), or one either side. For both tabs on the - # same side, T_av_left and T_av_right are equal, and the boundary condition - # "no tab" is used on the other side. + # Tab cooling only implemented for both tabs at the top. + negative_tab_area = self.param.l_tab_n * self.param.l_cn + positive_tab_area = self.param.l_tab_p * self.param.l_cp + total_top_area = self.param.l * self.param.l_y + non_tab_top_area = total_top_area - negative_tab_area - positive_tab_area + + negative_tab_cooling_coefficient = ( + self.param.h_tab_n / self.param.delta * negative_tab_area / total_top_area + ) + positive_tab_cooling_coefficient = ( + self.param.h_tab_p / self.param.delta * positive_tab_area / total_top_area + ) + + top_edge_cooling_coefficient = ( + self.param.h_edge / self.delta * non_tab_top_area / total_top_area + ) + + bottom_edge_cooling_coefficient = ( + self.param.h_edge / self.delta * total_top_area / total_top_area + ) + + total_top_cooling_coefficient = ( + negative_tab_cooling_coefficient + + positive_tab_cooling_coefficient + + top_edge_cooling_coefficient + ) + + total_bottom_cooling_coefficient = bottom_edge_cooling_coefficient + self.boundary_conditions = { T_av: { "negative tab": ( - self.param.h * (T_av_left - T_amb) / self.param.delta, + total_top_cooling_coefficient * (T_av_left - T_amb), "Neumann", ), "positive tab": ( - -self.param.h * (T_av_right - T_amb) / self.param.delta, + -total_bottom_cooling_coefficient * (T_av_right - T_amb), "Neumann", ), "no tab": (pybamm.Scalar(0), "Neumann"), diff --git a/pybamm/models/submodels/thermal/pouch_cell/pouch_cell_2D_current_collectors.py b/pybamm/models/submodels/thermal/pouch_cell/pouch_cell_2D_current_collectors.py index 8ebcae121c..0dd04bccec 100644 --- a/pybamm/models/submodels/thermal/pouch_cell/pouch_cell_2D_current_collectors.py +++ b/pybamm/models/submodels/thermal/pouch_cell/pouch_cell_2D_current_collectors.py @@ -60,11 +60,14 @@ def set_rhs(self, variables): # Account for surface area to volume ratio of pouch cell in cooling # coefficient. Note: the factor 1/delta^2 comes from the choice of # non-dimensionalisation - A = self.param.l_y * self.param.l_z - V = self.param.l * self.param.l_y * self.param.l_z - surface_cooling_coefficient = ( - -(self.param.h_cn + self.param.h_cp) * A / V / (self.param.delta ** 2) - ) # cooling on the y-z surfaces + yz_surface_area = self.param.l_y * self.param.l_z + cell_volume = self.param.l * self.param.l_y * self.param.l_z + yz_surface_cooling_coefficient = ( + -(self.param.h_cn + self.param.h_cp) + * yz_surface_area + / cell_volume + / (self.param.delta ** 2) + ) edge_cooling_coefficient = self.param.h_edge / self.param.delta @@ -77,7 +80,7 @@ def set_rhs(self, variables): T_av: ( pybamm.laplacian(T_av) + self.param.B * pybamm.source(Q_av, T_av) - + surface_cooling_coefficient * pybamm.source(T_av - T_amb, T_av) + + yz_surface_cooling_coefficient * pybamm.source(T_av - T_amb, T_av) - edge_cooling_coefficient * pybamm.source(T_av - T_amb, T_av, boundary=True) ) From 8cb709cff252636b956e87222042c7f3d39c754a Mon Sep 17 00:00:00 2001 From: Scott Marquis Date: Fri, 17 Apr 2020 16:33:43 +0100 Subject: [PATCH 03/15] #912 changed input files --- examples/scripts/example.py | 93 ++++++++++++++----- .../parameters.csv | 8 +- .../parameters.csv | 8 +- .../parameters.csv | 6 +- .../parameters.csv | 6 +- .../parameters.csv | 8 +- .../pouch_cell_1D_current_collectors.py | 4 +- .../pouch_cell_2D_current_collectors.py | 4 +- .../standard_parameters_lead_acid.py | 7 +- .../standard_parameters_lithium_ion.py | 8 +- 10 files changed, 115 insertions(+), 37 deletions(-) diff --git a/examples/scripts/example.py b/examples/scripts/example.py index 9b37e6a14c..782d18fd4a 100644 --- a/examples/scripts/example.py +++ b/examples/scripts/example.py @@ -3,29 +3,54 @@ import matplotlib.pyplot as plt +pybamm.set_logging_level("INFO") + +C_rate = 5 + options = { "thermal": "x-lumped", "current collector": "potential pair", - "dimensionality": 1, + "dimensionality": 2, } model = pybamm.lithium_ion.DFN(options=options) var = pybamm.standard_spatial_vars -# var_pts = { -# var.x_n: 5, -# var.x_s: 5, -# var.x_p: 5, -# var.r_n: 5, -# var.r_p: 5, -# var.y: 5, -# var.z: 5, -# } - -var_pts = None +var_pts = { + var.x_n: 5, + var.x_s: 5, + var.x_p: 5, + var.r_n: 5, + var.r_p: 5, + var.y: 5, + var.z: 5, +} + +# var_pts = None + +chemistry = pybamm.parameter_sets.NCA_Kim2011 +parameter_values = pybamm.ParameterValues(chemistry=chemistry) + +parameter_values.update( + { + "Negative current collector surface heat transfer coefficient [W.m-2.K-1]": 0, + "Positive current collector surface heat transfer coefficient [W.m-2.K-1]": 0, + "Negative tab heat transfer coefficient [W.m-2.K-1]": 0, + "Positive tab heat transfer coefficient [W.m-2.K-1]": 0, + "Edge heat transfer coefficient [W.m-2.K-1]": 500, + } +) solver = pybamm.CasadiSolver(mode="fast") -sim = pybamm.Simulation(model, var_pts=var_pts, solver=solver, C_rate=1) -sim.solve() +sim = pybamm.Simulation( + model, + var_pts=var_pts, + solver=solver, + parameter_values=parameter_values, + C_rate=C_rate, +) +t_eval = np.linspace(0, 3500 / 6, 100) +sim.solve(t_eval=t_eval) +# sim.plot(["X-averaged cell temperature [K]"]) t = sim.solution.t l_y = sim.parameter_values.evaluate(pybamm.geometric_parameters.l_y) @@ -33,19 +58,41 @@ y = np.linspace(0, l_y, 20) z = np.linspace(0, 1, 21) -cell_temp = sim.solution["X-averaged cell temperature [K]"](t=t, y=y, z=z) +T = sim.solution["X-averaged cell temperature [K]"](t=t[-1], y=y, z=z) +I = sim.solution["Current collector current density [A.m-2]"](t=t[-1], y=y, z=z) +fig, ax = plt.subplots(1, 3) +im = ax[0].pcolormesh( + y, + z, + np.transpose(T), + # vmin=-0.003, + # vmax=0, + shading="gouraud", + cmap="plasma", +) +plt.colorbar( + im, + ax=ax[0], + # format=ticker.FuncFormatter(fmt), + # orientation="horizontal", + # pad=0.2, + # format=sfmt, +) + + +cell_temp = sim.solution["X-averaged cell temperature [K]"].entries +# cell_temp = sim.solution["X-averaged cell temperature [K]"](t=t, y=cell_temp_var.y, z=z) # cell_temp = sim.solution["Negative current collector potential [V]"](t=t, y=y, z=z) -# max_temp = np.max(np.max(cell_temp, axis=0), axis=0) -# min_temp = np.min(np.min(cell_temp, axis=0), axis=0) -max_temp = np.max(cell_temp, axis=0) -min_temp = np.min(cell_temp, axis=0) +max_temp = np.max(np.max(cell_temp, axis=0), axis=0) +min_temp = np.min(np.min(cell_temp, axis=0), axis=0) +# max_temp = np.max(cell_temp, axis=0) +# min_temp = np.min(cell_temp, axis=0) delta_t = max_temp - min_temp -plt.plot(t, delta_t) -plt.show() +ax[1].plot(t, delta_t) -plt.plot(t, max_temp) -plt.plot(t, min_temp) +ax[2].plot(t, max_temp) +ax[2].plot(t, min_temp) plt.show() diff --git a/pybamm/input/parameters/lithium-ion/experiments/1C_charge_from_empty_Mohtat2020/parameters.csv b/pybamm/input/parameters/lithium-ion/experiments/1C_charge_from_empty_Mohtat2020/parameters.csv index ae32f40bb8..e843bfe334 100644 --- a/pybamm/input/parameters/lithium-ion/experiments/1C_charge_from_empty_Mohtat2020/parameters.csv +++ b/pybamm/input/parameters/lithium-ion/experiments/1C_charge_from_empty_Mohtat2020/parameters.csv @@ -3,10 +3,14 @@ Name [units],Value,Reference,Notes ,,, # Temperature Reference temperature [K],298.15,25C, -Heat transfer coefficient [W.m-2.K-1],5,Peyman MPM, +Negative current collector surface heat transfer coefficient [W.m-2.K-1],0,, +Positive current collector surface heat transfer coefficient [W.m-2.K-1],0,, +Negative tab heat transfer coefficient [W.m-2.K-1],0,, +Positive tab heat transfer coefficient [W.m-2.K-1],0,, +Edge heat transfer coefficient [W.m-2.K-1],5,Peyman MPM, Ambient temperature [K], 298.15,, ,,, -# Electrical +# Electrical Number of electrodes connected in parallel to make a cell,1,, Number of cells connected in series to make a battery,1,, Lower voltage cut-off [V],2.5,, diff --git a/pybamm/input/parameters/lithium-ion/experiments/1C_discharge_from_full_Chen2020/parameters.csv b/pybamm/input/parameters/lithium-ion/experiments/1C_discharge_from_full_Chen2020/parameters.csv index 7f59fcfd10..d91bb6f89b 100644 --- a/pybamm/input/parameters/lithium-ion/experiments/1C_discharge_from_full_Chen2020/parameters.csv +++ b/pybamm/input/parameters/lithium-ion/experiments/1C_discharge_from_full_Chen2020/parameters.csv @@ -3,11 +3,15 @@ Name [units],Value,Reference,Notes ,,, # Temperature Reference temperature [K],298.15,25C, -Heat transfer coefficient [W.m-2.K-1],10,, +Negative current collector surface heat transfer coefficient [W.m-2.K-1],0,, +Positive current collector surface heat transfer coefficient [W.m-2.K-1],0,, +Negative tab heat transfer coefficient [W.m-2.K-1],10,, +Positive tab heat transfer coefficient [W.m-2.K-1],10,, +Edge heat transfer coefficient [W.m-2.K-1],0.3,, Ambient temperature [K], 298.15,, ,,, -# Electrical +# Electrical Number of electrodes connected in parallel to make a cell,1,, Number of cells connected in series to make a battery,1,, Lower voltage cut-off [V],2.5,, diff --git a/pybamm/input/parameters/lithium-ion/experiments/1C_discharge_from_full_Ecker2015/parameters.csv b/pybamm/input/parameters/lithium-ion/experiments/1C_discharge_from_full_Ecker2015/parameters.csv index 131c087945..0397997a1b 100644 --- a/pybamm/input/parameters/lithium-ion/experiments/1C_discharge_from_full_Ecker2015/parameters.csv +++ b/pybamm/input/parameters/lithium-ion/experiments/1C_discharge_from_full_Ecker2015/parameters.csv @@ -3,7 +3,11 @@ Name [units],Value,Reference,Notes ,,, # Temperature Reference temperature [K],296.15,23C, -Heat transfer coefficient [W.m-2.K-1],10, The paper does not consider thermal effects so a typical value is chosen, +Negative current collector surface heat transfer coefficient [W.m-2.K-1],0,Paper does not consider thermal effects +Positive current collector surface heat transfer coefficient [W.m-2.K-1],0,Paper does not consider thermal effects +Negative tab heat transfer coefficient [W.m-2.K-1],10,Paper does not consider thermal effects, +Positive tab heat transfer coefficient [W.m-2.K-1],10,Paper does not consider thermal effects, +Edge heat transfer coefficient [W.m-2.K-1],0.3,Paper does not consider thermal effects, Ambient temperature [K], 298.15,, ,,, diff --git a/pybamm/input/parameters/lithium-ion/experiments/1C_discharge_from_full_Kim2011/parameters.csv b/pybamm/input/parameters/lithium-ion/experiments/1C_discharge_from_full_Kim2011/parameters.csv index e1e4b77c65..4d475c47e8 100644 --- a/pybamm/input/parameters/lithium-ion/experiments/1C_discharge_from_full_Kim2011/parameters.csv +++ b/pybamm/input/parameters/lithium-ion/experiments/1C_discharge_from_full_Kim2011/parameters.csv @@ -3,7 +3,11 @@ Name [units],Value,Reference,Notes ,,, # Temperature Reference temperature [K],298.15,25C, -Heat transfer coefficient [W.m-2.K-1],25,, +Negative current collector surface heat transfer coefficient [W.m-2.K-1],0,, +Positive current collector surface heat transfer coefficient [W.m-2.K-1],0,, +Negative tab heat transfer coefficient [W.m-2.K-1],25,, +Positive tab heat transfer coefficient [W.m-2.K-1],25,, +Edge heat transfer coefficient [W.m-2.K-1],0.3,, Ambient temperature [K], 298.15,, ,,, diff --git a/pybamm/input/parameters/lithium-ion/experiments/1C_discharge_from_full_Marquis2019/parameters.csv b/pybamm/input/parameters/lithium-ion/experiments/1C_discharge_from_full_Marquis2019/parameters.csv index bd463472c5..fb80497c1a 100644 --- a/pybamm/input/parameters/lithium-ion/experiments/1C_discharge_from_full_Marquis2019/parameters.csv +++ b/pybamm/input/parameters/lithium-ion/experiments/1C_discharge_from_full_Marquis2019/parameters.csv @@ -4,9 +4,13 @@ Name [units],Value,Reference,Notes # Temperature Reference temperature [K],298.15,25C, Ambient temperature [K], 298.15,, -Heat transfer coefficient [W.m-2.K-1],10,, +Negative current collector surface heat transfer coefficient [W.m-2.K-1],0,, +Positive current collector surface heat transfer coefficient [W.m-2.K-1],0,, +Negative tab heat transfer coefficient [W.m-2.K-1],10,, +Positive tab heat transfer coefficient [W.m-2.K-1],10,, +Edge heat transfer coefficient [W.m-2.K-1],0.3,, ,,, -# Electrical +# Electrical Number of electrodes connected in parallel to make a cell,1,, Number of cells connected in series to make a battery,1,, Lower voltage cut-off [V],3.105,, diff --git a/pybamm/models/submodels/thermal/pouch_cell/pouch_cell_1D_current_collectors.py b/pybamm/models/submodels/thermal/pouch_cell/pouch_cell_1D_current_collectors.py index eaf1394b32..15f025e50e 100644 --- a/pybamm/models/submodels/thermal/pouch_cell/pouch_cell_1D_current_collectors.py +++ b/pybamm/models/submodels/thermal/pouch_cell/pouch_cell_1D_current_collectors.py @@ -108,11 +108,11 @@ def set_boundary_conditions(self, variables): ) top_edge_cooling_coefficient = ( - self.param.h_edge / self.delta * non_tab_top_area / total_top_area + self.param.h_edge / self.param.delta * non_tab_top_area / total_top_area ) bottom_edge_cooling_coefficient = ( - self.param.h_edge / self.delta * total_top_area / total_top_area + self.param.h_edge / self.param.delta * total_top_area / total_top_area ) total_top_cooling_coefficient = ( diff --git a/pybamm/models/submodels/thermal/pouch_cell/pouch_cell_2D_current_collectors.py b/pybamm/models/submodels/thermal/pouch_cell/pouch_cell_2D_current_collectors.py index 0dd04bccec..36aa2e5a51 100644 --- a/pybamm/models/submodels/thermal/pouch_cell/pouch_cell_2D_current_collectors.py +++ b/pybamm/models/submodels/thermal/pouch_cell/pouch_cell_2D_current_collectors.py @@ -113,8 +113,8 @@ def set_boundary_conditions(self, variables): self.boundary_conditions = { T_av: { - "negative tab": -(h_tab_n_corrected * (T_av_n - T_amb), "Neumann"), - "positive tab": -(h_tab_p_corrected * (T_av_p - T_amb), "Neumann"), + "negative tab": (-h_tab_n_corrected * (T_av_n - T_amb), "Neumann"), + "positive tab": (-h_tab_p_corrected * (T_av_p - T_amb), "Neumann"), } } diff --git a/pybamm/parameters/standard_parameters_lead_acid.py b/pybamm/parameters/standard_parameters_lead_acid.py index 6cb4516426..b2d5d557cd 100644 --- a/pybamm/parameters/standard_parameters_lead_acid.py +++ b/pybamm/parameters/standard_parameters_lead_acid.py @@ -458,7 +458,12 @@ def U_p_dimensional(c_e, T): lambda_k = pybamm.thermal_parameters.lambda_k Theta = pybamm.thermal_parameters.Theta -h = pybamm.thermal_parameters.h + +h_edge = pybamm.thermal_parameters.h_edge +h_tab_n = pybamm.thermal_parameters.h_tab_n +h_tab_p = pybamm.thermal_parameters.h_tab_p +h_cn = pybamm.thermal_parameters.h_cn +h_cp = pybamm.thermal_parameters.h_cp B = ( i_typ * R diff --git a/pybamm/parameters/standard_parameters_lithium_ion.py b/pybamm/parameters/standard_parameters_lithium_ion.py index 0571fa9cb6..499d73569f 100644 --- a/pybamm/parameters/standard_parameters_lithium_ion.py +++ b/pybamm/parameters/standard_parameters_lithium_ion.py @@ -381,7 +381,13 @@ def chi(c_e): lambda_k = pybamm.thermal_parameters.lambda_k Theta = pybamm.thermal_parameters.Theta -h = pybamm.thermal_parameters.h + +h_edge = pybamm.thermal_parameters.h_edge +h_tab_n = pybamm.thermal_parameters.h_tab_n +h_tab_p = pybamm.thermal_parameters.h_tab_p +h_cn = pybamm.thermal_parameters.h_cn +h_cp = pybamm.thermal_parameters.h_cp + B = ( i_typ * R From e9eeea7a206e8ece04923e4bea571fad59a2a62f Mon Sep 17 00:00:00 2001 From: Scott Marquis Date: Mon, 20 Apr 2020 09:14:34 +0100 Subject: [PATCH 04/15] #912 playing around to test --- examples/scripts/example.py | 14 +-- examples/scripts/example_lumped.py | 135 +++++++++++++++++++++++++++++ 2 files changed, 142 insertions(+), 7 deletions(-) create mode 100644 examples/scripts/example_lumped.py diff --git a/examples/scripts/example.py b/examples/scripts/example.py index 782d18fd4a..bc751fe0f7 100644 --- a/examples/scripts/example.py +++ b/examples/scripts/example.py @@ -16,13 +16,13 @@ var = pybamm.standard_spatial_vars var_pts = { - var.x_n: 5, - var.x_s: 5, - var.x_p: 5, - var.r_n: 5, - var.r_p: 5, - var.y: 5, - var.z: 5, + var.x_n: 7, + var.x_s: 7, + var.x_p: 7, + var.r_n: 7, + var.r_p: 7, + var.y: 7, + var.z: 7, } # var_pts = None diff --git a/examples/scripts/example_lumped.py b/examples/scripts/example_lumped.py new file mode 100644 index 0000000000..e0af01f067 --- /dev/null +++ b/examples/scripts/example_lumped.py @@ -0,0 +1,135 @@ +import pybamm +import numpy as np +import matplotlib.pyplot as plt + + +pybamm.set_logging_level("INFO") + +C_rate = 5 + +options = { + "thermal": "x-lumped", + # "current collector": "potential pair", + # "dimensionality": 2, +} +dfn_1D = pybamm.lithium_ion.DFN(options=options) + +options = { + "thermal": "x-lumped", + "current collector": "potential pair", + "dimensionality": 1, +} +dfn_1p1D = pybamm.lithium_ion.DFN(options=options) + +options = { + "thermal": "x-lumped", + "current collector": "potential pair", + "dimensionality": 2, +} +dfn_2p1D = pybamm.lithium_ion.DFN(options=options) + +models = {"DFN 1D": dfn_1D, "DFN 1+1D": dfn_1p1D, "DFN 2+1D": dfn_2p1D} + +solutions = {} +other_vars = {} + +for model_name, model in models.items(): + + var = pybamm.standard_spatial_vars + var_pts = { + var.x_n: 3, + var.x_s: 3, + var.x_p: 3, + var.r_n: 3, + var.r_p: 3, + var.y: 5, + var.z: 5, + } + + # var_pts = None + + chemistry = pybamm.parameter_sets.NCA_Kim2011 + parameter_values = pybamm.ParameterValues(chemistry=chemistry) + + parameter_values.update( + { + "Negative current collector surface heat transfer coefficient [W.m-2.K-1]": 0, + "Positive current collector surface heat transfer coefficient [W.m-2.K-1]": 0, + "Negative tab heat transfer coefficient [W.m-2.K-1]": 0, + "Positive tab heat transfer coefficient [W.m-2.K-1]": 0, + "Edge heat transfer coefficient [W.m-2.K-1]": 500, + "Negative current collector thermal conductivity [W.m-1.K-1]": 267.467 + * 100000, + "Positive current collector thermal conductivity [W.m-1.K-1]": 158.079 + * 100000, + "Negative current collector conductivity [S.m-1]": 1e10, + "Positive current collector conductivity [S.m-1]": 1e10, + } + ) + + solver = pybamm.CasadiSolver(mode="fast") + sim = pybamm.Simulation( + model, + var_pts=var_pts, + solver=solver, + parameter_values=parameter_values, + C_rate=C_rate, + ) + t_eval = np.linspace(0, 3500 / 6, 100) + sim.solve(t_eval=t_eval) + + solutions[model_name] = sim.solution + + av = sim.solution["Volume-averaged cell temperature [K]"].entries + + if model_name == "DFN 2+1D": + cell_temp = sim.solution["X-averaged cell temperature [K]"].entries + max_temp = np.max(np.max(cell_temp, axis=0), axis=0) + min_temp = np.min(np.min(cell_temp, axis=0), axis=0) + + elif model_name == "DFN 1+1D": + cell_temp = sim.solution["X-averaged cell temperature [K]"].entries + max_temp = np.max(cell_temp, axis=0) + min_temp = np.min(cell_temp, axis=0) + + elif model_name == "DFN 1D": + max_temp = sim.solution["Volume-averaged cell temperature [K]"].entries + min_temp = sim.solution["Volume-averaged cell temperature [K]"].entries + + other_vars[model_name] = { + "Time [s]": sim.solution["Time [s]"].entries, + "Max temperature [K]": max_temp, + "Min temperature [K]": min_temp, + "Volume-averaged cell temperature [K]": av, + } + +# sim.plot(["X-averaged cell temperature [K]"]) + +plot = pybamm.QuickPlot( + list(solutions.values()), output_variables=["Volume-averaged cell temperature [K]"] +) +plot.dynamic_plot() + +fig, ax = plt.subplots(1, 3) + +for i, model_name in enumerate(list(models.keys())): + ax[0].plot( + other_vars[model_name]["Time [s]"], + other_vars[model_name]["Max temperature [K]"], + label=model_name, + ) + ax[1].plot( + other_vars[model_name]["Time [s]"], + other_vars[model_name]["Min temperature [K]"], + label=model_name, + ) + ax[2].plot( + other_vars[model_name]["Time [s]"], + other_vars[model_name]["Volume-averaged cell temperature [K]"], + label=model_name, + ) + + +ax[2].legend() + +plt.show() From d05c154217a51edbd28952c04716690ac6cd125c Mon Sep 17 00:00:00 2001 From: Scott Marquis Date: Mon, 20 Apr 2020 09:21:25 +0100 Subject: [PATCH 05/15] #912 updated lead acid parameter file --- .../experiments/1C_discharge_from_full/parameters.csv | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/pybamm/input/parameters/lead-acid/experiments/1C_discharge_from_full/parameters.csv b/pybamm/input/parameters/lead-acid/experiments/1C_discharge_from_full/parameters.csv index 154de5565e..18cc3b5eac 100644 --- a/pybamm/input/parameters/lead-acid/experiments/1C_discharge_from_full/parameters.csv +++ b/pybamm/input/parameters/lead-acid/experiments/1C_discharge_from_full/parameters.csv @@ -5,8 +5,11 @@ Name [units],Value,Reference,Notes Reference temperature [K],294.85,Room temperature, Maximum temperature [K],333.15,, Ambient temperature [K], 294.85,, -Heat transfer coefficient [W.m-2.K-1],10,, -Initial temperature [K],294.85,Room temperature, +Negative current collector surface heat transfer coefficient [W.m-2.K-1],0,, +Positive current collector surface heat transfer coefficient [W.m-2.K-1],0,, +Negative tab heat transfer coefficient [W.m-2.K-1],10,, +Positive tab heat transfer coefficient [W.m-2.K-1],10,, +Edge heat transfer coefficient [W.m-2.K-1],0.3,, ,,, # Electrical @@ -18,3 +21,4 @@ Upper voltage cut-off [V],2.44,(just over) 14.5V across 6-cell battery, # Initial conditions Initial State of Charge,1,-, Initial oxygen concentration [mol.m-3],0,, +Initial temperature [K],294.85,Room temperature, From 456af64ed3ed56e21170b9c36271fb776e0e7622 Mon Sep 17 00:00:00 2001 From: Scott Marquis Date: Mon, 20 Apr 2020 09:24:36 +0100 Subject: [PATCH 06/15] #912 updated x-full thermal model --- pybamm/models/submodels/thermal/x_full.py | 6 ++++-- pybamm/parameters/standard_parameters_lead_acid.py | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/pybamm/models/submodels/thermal/x_full.py b/pybamm/models/submodels/thermal/x_full.py index 2331a2de04..41f8d75d94 100644 --- a/pybamm/models/submodels/thermal/x_full.py +++ b/pybamm/models/submodels/thermal/x_full.py @@ -63,14 +63,16 @@ def set_boundary_conditions(self, variables): T_p_right = pybamm.boundary_value(T, "right") T_amb = variables["Ambient temperature"] + # N.B only y-z surface cooling is implemented for this thermal model. + # Tab and edge cooling is not accounted for. self.boundary_conditions = { T: { "left": ( - self.param.h * (T_n_left - T_amb) / self.param.lambda_n, + self.param.h_cn * (T_n_left - T_amb) / self.param.lambda_n, "Neumann", ), "right": ( - -self.param.h * (T_p_right - T_amb) / self.param.lambda_p, + -self.param.h_cp * (T_p_right - T_amb) / self.param.lambda_p, "Neumann", ), } diff --git a/pybamm/parameters/standard_parameters_lead_acid.py b/pybamm/parameters/standard_parameters_lead_acid.py index b2d5d557cd..fce599c2b1 100644 --- a/pybamm/parameters/standard_parameters_lead_acid.py +++ b/pybamm/parameters/standard_parameters_lead_acid.py @@ -464,6 +464,7 @@ def U_p_dimensional(c_e, T): h_tab_p = pybamm.thermal_parameters.h_tab_p h_cn = pybamm.thermal_parameters.h_cn h_cp = pybamm.thermal_parameters.h_cp + B = ( i_typ * R From 6c03007351ca80b891b8fda17ec621ad1d393b64 Mon Sep 17 00:00:00 2001 From: Scott Marquis Date: Mon, 20 Apr 2020 09:40:49 +0100 Subject: [PATCH 07/15] #912 removed h from dimensionless parameters tests --- .../test_dimensionless_parameter_values_lithium_ion.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/unit/test_parameters/test_dimensionless_parameter_values_lithium_ion.py b/tests/unit/test_parameters/test_dimensionless_parameter_values_lithium_ion.py index 7c7dd3000c..cfd5f2869a 100644 --- a/tests/unit/test_parameters/test_dimensionless_parameter_values_lithium_ion.py +++ b/tests/unit/test_parameters/test_dimensionless_parameter_values_lithium_ion.py @@ -172,8 +172,6 @@ def test_thermal_parameters(self): np.testing.assert_almost_equal(values.evaluate(param.Theta / c_rate), 0.008, 2) - np.testing.assert_almost_equal(values.evaluate(param.h), 3.7881 * 10 ** (-5), 7) - # np.testing.assert_almost_equal( # values.evaluate(param.B / c_rate), 36.216, 2 # ) From a1d786685f46ef0ebab7a153a4ad5f83d8ab2d8e Mon Sep 17 00:00:00 2001 From: Scott Marquis Date: Mon, 20 Apr 2020 12:22:17 +0100 Subject: [PATCH 08/15] #912 updated 1+1D cooling and added thermal consistency test --- examples/scripts/example.py | 98 ------------- examples/scripts/example_lumped.py | 135 ------------------ .../pouch_cell_1D_current_collectors.py | 16 ++- .../test_lithium_ion/test_thermal_models.py | 106 ++++++++++++++ 4 files changed, 115 insertions(+), 240 deletions(-) delete mode 100644 examples/scripts/example.py delete mode 100644 examples/scripts/example_lumped.py create mode 100644 tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_thermal_models.py diff --git a/examples/scripts/example.py b/examples/scripts/example.py deleted file mode 100644 index bc751fe0f7..0000000000 --- a/examples/scripts/example.py +++ /dev/null @@ -1,98 +0,0 @@ -import pybamm -import numpy as np -import matplotlib.pyplot as plt - - -pybamm.set_logging_level("INFO") - -C_rate = 5 - -options = { - "thermal": "x-lumped", - "current collector": "potential pair", - "dimensionality": 2, -} -model = pybamm.lithium_ion.DFN(options=options) - -var = pybamm.standard_spatial_vars -var_pts = { - var.x_n: 7, - var.x_s: 7, - var.x_p: 7, - var.r_n: 7, - var.r_p: 7, - var.y: 7, - var.z: 7, -} - -# var_pts = None - -chemistry = pybamm.parameter_sets.NCA_Kim2011 -parameter_values = pybamm.ParameterValues(chemistry=chemistry) - -parameter_values.update( - { - "Negative current collector surface heat transfer coefficient [W.m-2.K-1]": 0, - "Positive current collector surface heat transfer coefficient [W.m-2.K-1]": 0, - "Negative tab heat transfer coefficient [W.m-2.K-1]": 0, - "Positive tab heat transfer coefficient [W.m-2.K-1]": 0, - "Edge heat transfer coefficient [W.m-2.K-1]": 500, - } -) - -solver = pybamm.CasadiSolver(mode="fast") -sim = pybamm.Simulation( - model, - var_pts=var_pts, - solver=solver, - parameter_values=parameter_values, - C_rate=C_rate, -) -t_eval = np.linspace(0, 3500 / 6, 100) -sim.solve(t_eval=t_eval) -# sim.plot(["X-averaged cell temperature [K]"]) - -t = sim.solution.t -l_y = sim.parameter_values.evaluate(pybamm.geometric_parameters.l_y) -x = np.linspace(0, 1, 19) -y = np.linspace(0, l_y, 20) -z = np.linspace(0, 1, 21) - -T = sim.solution["X-averaged cell temperature [K]"](t=t[-1], y=y, z=z) -I = sim.solution["Current collector current density [A.m-2]"](t=t[-1], y=y, z=z) -fig, ax = plt.subplots(1, 3) -im = ax[0].pcolormesh( - y, - z, - np.transpose(T), - # vmin=-0.003, - # vmax=0, - shading="gouraud", - cmap="plasma", -) -plt.colorbar( - im, - ax=ax[0], - # format=ticker.FuncFormatter(fmt), - # orientation="horizontal", - # pad=0.2, - # format=sfmt, -) - - -cell_temp = sim.solution["X-averaged cell temperature [K]"].entries -# cell_temp = sim.solution["X-averaged cell temperature [K]"](t=t, y=cell_temp_var.y, z=z) -# cell_temp = sim.solution["Negative current collector potential [V]"](t=t, y=y, z=z) -max_temp = np.max(np.max(cell_temp, axis=0), axis=0) -min_temp = np.min(np.min(cell_temp, axis=0), axis=0) -# max_temp = np.max(cell_temp, axis=0) -# min_temp = np.min(cell_temp, axis=0) -delta_t = max_temp - min_temp - - -ax[1].plot(t, delta_t) - -ax[2].plot(t, max_temp) -ax[2].plot(t, min_temp) - -plt.show() diff --git a/examples/scripts/example_lumped.py b/examples/scripts/example_lumped.py deleted file mode 100644 index e0af01f067..0000000000 --- a/examples/scripts/example_lumped.py +++ /dev/null @@ -1,135 +0,0 @@ -import pybamm -import numpy as np -import matplotlib.pyplot as plt - - -pybamm.set_logging_level("INFO") - -C_rate = 5 - -options = { - "thermal": "x-lumped", - # "current collector": "potential pair", - # "dimensionality": 2, -} -dfn_1D = pybamm.lithium_ion.DFN(options=options) - -options = { - "thermal": "x-lumped", - "current collector": "potential pair", - "dimensionality": 1, -} -dfn_1p1D = pybamm.lithium_ion.DFN(options=options) - -options = { - "thermal": "x-lumped", - "current collector": "potential pair", - "dimensionality": 2, -} -dfn_2p1D = pybamm.lithium_ion.DFN(options=options) - -models = {"DFN 1D": dfn_1D, "DFN 1+1D": dfn_1p1D, "DFN 2+1D": dfn_2p1D} - -solutions = {} -other_vars = {} - -for model_name, model in models.items(): - - var = pybamm.standard_spatial_vars - var_pts = { - var.x_n: 3, - var.x_s: 3, - var.x_p: 3, - var.r_n: 3, - var.r_p: 3, - var.y: 5, - var.z: 5, - } - - # var_pts = None - - chemistry = pybamm.parameter_sets.NCA_Kim2011 - parameter_values = pybamm.ParameterValues(chemistry=chemistry) - - parameter_values.update( - { - "Negative current collector surface heat transfer coefficient [W.m-2.K-1]": 0, - "Positive current collector surface heat transfer coefficient [W.m-2.K-1]": 0, - "Negative tab heat transfer coefficient [W.m-2.K-1]": 0, - "Positive tab heat transfer coefficient [W.m-2.K-1]": 0, - "Edge heat transfer coefficient [W.m-2.K-1]": 500, - "Negative current collector thermal conductivity [W.m-1.K-1]": 267.467 - * 100000, - "Positive current collector thermal conductivity [W.m-1.K-1]": 158.079 - * 100000, - "Negative current collector conductivity [S.m-1]": 1e10, - "Positive current collector conductivity [S.m-1]": 1e10, - } - ) - - solver = pybamm.CasadiSolver(mode="fast") - sim = pybamm.Simulation( - model, - var_pts=var_pts, - solver=solver, - parameter_values=parameter_values, - C_rate=C_rate, - ) - t_eval = np.linspace(0, 3500 / 6, 100) - sim.solve(t_eval=t_eval) - - solutions[model_name] = sim.solution - - av = sim.solution["Volume-averaged cell temperature [K]"].entries - - if model_name == "DFN 2+1D": - cell_temp = sim.solution["X-averaged cell temperature [K]"].entries - max_temp = np.max(np.max(cell_temp, axis=0), axis=0) - min_temp = np.min(np.min(cell_temp, axis=0), axis=0) - - elif model_name == "DFN 1+1D": - cell_temp = sim.solution["X-averaged cell temperature [K]"].entries - max_temp = np.max(cell_temp, axis=0) - min_temp = np.min(cell_temp, axis=0) - - elif model_name == "DFN 1D": - max_temp = sim.solution["Volume-averaged cell temperature [K]"].entries - min_temp = sim.solution["Volume-averaged cell temperature [K]"].entries - - other_vars[model_name] = { - "Time [s]": sim.solution["Time [s]"].entries, - "Max temperature [K]": max_temp, - "Min temperature [K]": min_temp, - "Volume-averaged cell temperature [K]": av, - } - -# sim.plot(["X-averaged cell temperature [K]"]) - -plot = pybamm.QuickPlot( - list(solutions.values()), output_variables=["Volume-averaged cell temperature [K]"] -) -plot.dynamic_plot() - -fig, ax = plt.subplots(1, 3) - -for i, model_name in enumerate(list(models.keys())): - ax[0].plot( - other_vars[model_name]["Time [s]"], - other_vars[model_name]["Max temperature [K]"], - label=model_name, - ) - ax[1].plot( - other_vars[model_name]["Time [s]"], - other_vars[model_name]["Min temperature [K]"], - label=model_name, - ) - ax[2].plot( - other_vars[model_name]["Time [s]"], - other_vars[model_name]["Volume-averaged cell temperature [K]"], - label=model_name, - ) - - -ax[2].legend() - -plt.show() diff --git a/pybamm/models/submodels/thermal/pouch_cell/pouch_cell_1D_current_collectors.py b/pybamm/models/submodels/thermal/pouch_cell/pouch_cell_1D_current_collectors.py index 15f025e50e..3b47bf1604 100644 --- a/pybamm/models/submodels/thermal/pouch_cell/pouch_cell_1D_current_collectors.py +++ b/pybamm/models/submodels/thermal/pouch_cell/pouch_cell_1D_current_collectors.py @@ -91,8 +91,8 @@ def set_rhs(self, variables): def set_boundary_conditions(self, variables): T_amb = variables["Ambient temperature"] T_av = variables["X-averaged cell temperature"] - T_av_left = pybamm.boundary_value(T_av, "negative tab") - T_av_right = pybamm.boundary_value(T_av, "positive tab") + T_av_top = pybamm.boundary_value(T_av, "right") + T_av_bottom = pybamm.boundary_value(T_av, "left") # Tab cooling only implemented for both tabs at the top. negative_tab_area = self.param.l_tab_n * self.param.l_cn @@ -123,17 +123,19 @@ def set_boundary_conditions(self, variables): total_bottom_cooling_coefficient = bottom_edge_cooling_coefficient + # just use left and right for clarity + # left = bottom of cell (z=0) + # right = top of cell (z=L_z) self.boundary_conditions = { T_av: { - "negative tab": ( - total_top_cooling_coefficient * (T_av_left - T_amb), + "left": ( + total_bottom_cooling_coefficient * (T_av_bottom - T_amb), "Neumann", ), - "positive tab": ( - -total_bottom_cooling_coefficient * (T_av_right - T_amb), + "right": ( + -total_top_cooling_coefficient * (T_av_top - T_amb), "Neumann", ), - "no tab": (pybamm.Scalar(0), "Neumann"), } } diff --git a/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_thermal_models.py b/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_thermal_models.py new file mode 100644 index 0000000000..4c1afb9002 --- /dev/null +++ b/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_thermal_models.py @@ -0,0 +1,106 @@ +# +# Tests for the thermal lithium-ion models produce consistent +# thermal response +# +import pybamm +import tests +import numpy as np +import unittest + + +class TestThermal(unittest.TestCase): + def test_consistent_cooling(self): + # use spme for comparison instead of spm as + # much larger realistic temperature rises + # so that errors can be more easily observed + C_rate = 5 + options = { + "thermal": "x-lumped", + } + spme_1D = pybamm.lithium_ion.SPMe(options=options) + + options = { + "thermal": "x-lumped", + "current collector": "potential pair", + "dimensionality": 1, + } + spme_1p1D = pybamm.lithium_ion.SPMe(options=options) + + options = { + "thermal": "x-lumped", + "current collector": "potential pair", + "dimensionality": 2, + } + spme_2p1D = pybamm.lithium_ion.SPMe(options=options) + + models = {"SPMe 1D": spme_1D, "SPMe 1+1D": spme_1p1D, "SPMe 2+1D": spme_2p1D} + solutions = {} + + for model_name, model in models.items(): + var = pybamm.standard_spatial_vars + var_pts = { + var.x_n: 3, + var.x_s: 3, + var.x_p: 3, + var.r_n: 3, + var.r_p: 3, + var.y: 5, + var.z: 5, + } + chemistry = pybamm.parameter_sets.NCA_Kim2011 + parameter_values = pybamm.ParameterValues(chemistry=chemistry) + + # high thermal and electrical conductivity in current collectors + parameter_values.update( + { + "Negative current collector" + + " surface heat transfer coefficient [W.m-2.K-1]": 10, + "Positive current collector" + + " surface heat transfer coefficient [W.m-2.K-1]": 5, + "Negative tab heat transfer coefficient [W.m-2.K-1]": 250, + "Positive tab heat transfer coefficient [W.m-2.K-1]": 250, + "Edge heat transfer coefficient [W.m-2.K-1]": 100, + "Negative current collector" + + " thermal conductivity [W.m-1.K-1]": 267.467 * 100000, + "Positive current collector" + + " thermal conductivity [W.m-1.K-1]": 158.079 * 100000, + "Negative current collector conductivity [S.m-1]": 1e10, + "Positive current collector conductivity [S.m-1]": 1e10, + } + ) + + solver = pybamm.CasadiSolver(mode="fast") + sim = pybamm.Simulation( + model, + var_pts=var_pts, + solver=solver, + parameter_values=parameter_values, + C_rate=C_rate, + ) + t_eval = np.linspace(0, 3500 / 6, 100) + sim.solve(t_eval=t_eval) + + solutions[model_name] = sim.solution[ + "Volume-averaged cell temperature [K]" + ].entries + + # check volume-averaged cell temperature is within + # 1e-5 relative error + + def err(a, b): + return np.max(np.abs(a - b)) / np.max(np.abs(a)) + + self.assertGreater(1e-5, err(solutions["SPMe 1D"], solutions["SPMe 1+1D"])) + self.assertGreater(1e-5, err(solutions["SPMe 1D"], solutions["SPMe 2+1D"])) + self.assertGreater(1e-5, err(solutions["SPMe 1+1D"], solutions["SPMe 2+1D"])) + + +if __name__ == "__main__": + print("Add -v for more debug output") + import sys + + sys.setrecursionlimit(10000) + + if "-v" in sys.argv: + debug = True + unittest.main() From 377cd43fcee4ba3ae890e1f49931cfcdf8448d2a Mon Sep 17 00:00:00 2001 From: Scott Marquis Date: Mon, 20 Apr 2020 12:25:01 +0100 Subject: [PATCH 09/15] #912 updated changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f940e63a82..2cfb246676 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Features +- Added tab, edge, and surface cooling ([#965](https://github.com/pybamm-team/PyBaMM/pull/965)) - Added functionality to solver to automatically discretise a 0D model ([#947](https://github.com/pybamm-team/PyBaMM/pull/947)) - Added sensitivity to `CasadiAlgebraicSolver` ([#940](https://github.com/pybamm-team/PyBaMM/pull/940)) - Added `ProcessedSymbolicVariable` class, which can handle symbolic variables (i.e. variables for which the inputs are symbolic) ([#940](https://github.com/pybamm-team/PyBaMM/pull/940)) From 097d777e82d0407cd5c0631335ebe9af58f88c5e Mon Sep 17 00:00:00 2001 From: Scott Marquis Date: Mon, 20 Apr 2020 14:50:50 +0100 Subject: [PATCH 10/15] #912 updated example script --- examples/scripts/thermal_lithium_ion.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/examples/scripts/thermal_lithium_ion.py b/examples/scripts/thermal_lithium_ion.py index f9766b4f0d..cd4c1fbdea 100644 --- a/examples/scripts/thermal_lithium_ion.py +++ b/examples/scripts/thermal_lithium_ion.py @@ -18,7 +18,20 @@ # load parameter values and process models and geometry param = models[0].default_parameter_values -param.update({"Heat transfer coefficient [W.m-2.K-1]": 1}) + +# for x-full, cooling is only implemented on the surfaces +# so set other forms of cooling to zero for comparison. +param.update( + { + "Negative current collector" + + " surface heat transfer coefficient [W.m-2.K-1]": 5, + "Positive current collector" + + " surface heat transfer coefficient [W.m-2.K-1]": 5, + "Negative tab heat transfer coefficient [W.m-2.K-1]": 0, + "Positive tab heat transfer coefficient [W.m-2.K-1]": 0, + "Edge heat transfer coefficient [W.m-2.K-1]": 0, + } +) for model in models: param.process_model(model) From e47f737cd1a8e463c8f512b3198f8f34ebf90dd6 Mon Sep 17 00:00:00 2001 From: Scott Marquis Date: Mon, 20 Apr 2020 15:11:31 +0100 Subject: [PATCH 11/15] #912 updated compare outputs test --- .../test_lithium_ion/test_compare_outputs.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_compare_outputs.py b/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_compare_outputs.py index 63a076abf7..30eecc79ab 100644 --- a/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_compare_outputs.py +++ b/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_compare_outputs.py @@ -64,6 +64,20 @@ def test_compare_outputs_thermal(self): for models in model_combos: # load parameter values (same for all models) param = models[0].default_parameter_values + + # for x-full, cooling is only implemented on the surfaces + # so set other forms of cooling to zero for comparison. + param.update( + { + "Negative current collector" + + " surface heat transfer coefficient [W.m-2.K-1]": 5, + "Positive current collector" + + " surface heat transfer coefficient [W.m-2.K-1]": 5, + "Negative tab heat transfer coefficient [W.m-2.K-1]": 0, + "Positive tab heat transfer coefficient [W.m-2.K-1]": 0, + "Edge heat transfer coefficient [W.m-2.K-1]": 0, + } + ) for model in models: param.process_model(model) From f465c9e7c60d81af53aa3a7d57513507a55a6bee Mon Sep 17 00:00:00 2001 From: Scott Marquis Date: Mon, 20 Apr 2020 15:16:36 +0100 Subject: [PATCH 12/15] #912 updated thermal notebook --- .../using-model-options_thermal-example.ipynb | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/examples/notebooks/using-model-options_thermal-example.ipynb b/examples/notebooks/using-model-options_thermal-example.ipynb index 851ae6ef5a..6a089069c7 100644 --- a/examples/notebooks/using-model-options_thermal-example.ipynb +++ b/examples/notebooks/using-model-options_thermal-example.ipynb @@ -65,7 +65,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "We choose to use the parameters from [1]. We then update the heat transfer coefficient to be 0.1 [W/m^2/K] (see the [Parameter Values notebook](./parameter-values.ipynb) for more details)" + "We choose to use the parameters from [1]. We then update the heat transfer coefficients (see the [Parameter Values notebook](./parameter-values.ipynb) for more details)" ] }, { @@ -75,7 +75,17 @@ "outputs": [], "source": [ "param = pybamm.ParameterValues(chemistry=pybamm.parameter_sets.Marquis2019)\n", - "param.update({\"Heat transfer coefficient [W.m-2.K-1]\": 0.1})" + "param.update(\n", + " {\n", + " \"Negative current collector\"\n", + " + \" surface heat transfer coefficient [W.m-2.K-1]\": 5,\n", + " \"Positive current collector\"\n", + " + \" surface heat transfer coefficient [W.m-2.K-1]\": 5,\n", + " \"Negative tab heat transfer coefficient [W.m-2.K-1]\": 0,\n", + " \"Positive tab heat transfer coefficient [W.m-2.K-1]\": 0,\n", + " \"Edge heat transfer coefficient [W.m-2.K-1]\": 0,\n", + " }\n", + ")" ] }, { @@ -121,7 +131,7 @@ "source": [ "# solve model\n", "solver = model.default_solver\n", - "t_eval = np.linspace(0, 1, 250)\n", + "t_eval = np.linspace(0, 3600, 250)\n", "solution = solver.solve(model, t_eval)" ] }, @@ -140,12 +150,12 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "c3d04dd597c24caf83c370bd01fe6131", + "model_id": "115696cc7c7e4297bb6d85a9f8220a82", "version_major": 2, "version_minor": 0 }, "text/plain": [ - "interactive(children=(FloatSlider(value=0.0, description='t', max=1.0, step=0.01), Output()), _dom_classes=('w…" + "interactive(children=(FloatSlider(value=0.0, description='t', max=3599.9999999999995, step=35.99999999999999),…" ] }, "metadata": {}, @@ -202,9 +212,9 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.3" + "version": "3.7.5" } }, "nbformat": 4, "nbformat_minor": 2 -} \ No newline at end of file +} From fcf1ece2a207963169f7e02c73a129b1d610f233 Mon Sep 17 00:00:00 2001 From: Scott Marquis Date: Mon, 20 Apr 2020 15:54:34 +0100 Subject: [PATCH 13/15] #912 fixed tests --- .../test_lithium_ion/test_thermal_models.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_thermal_models.py b/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_thermal_models.py index 4c1afb9002..22d9ce6d6b 100644 --- a/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_thermal_models.py +++ b/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_thermal_models.py @@ -3,7 +3,6 @@ # thermal response # import pybamm -import tests import numpy as np import unittest From a45952849eb758c3b8fd00e3d26b9a6e04d090f6 Mon Sep 17 00:00:00 2001 From: Scott Marquis Date: Tue, 28 Apr 2020 16:59:37 +0100 Subject: [PATCH 14/15] #912 added warning --- pybamm/models/full_battery_models/base_battery_model.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pybamm/models/full_battery_models/base_battery_model.py b/pybamm/models/full_battery_models/base_battery_model.py index 4e4c2673f6..6aa5caf626 100644 --- a/pybamm/models/full_battery_models/base_battery_model.py +++ b/pybamm/models/full_battery_models/base_battery_model.py @@ -3,6 +3,7 @@ # import pybamm +import warnings class BaseBatteryModel(pybamm.BaseModel): @@ -239,6 +240,11 @@ def options(self, extra_options): "particle model '{}' not recognised".format(options["particle"]) ) + if options["thermal"] == "x-lumped" and options["dimensionality"] == 1: + warnings.warn( + "1+1D Thermal models are only valid if both tabs are places at the top of the cell." + ) + self._options = options def set_standard_output_variables(self): From 08d957d0d2d7092236b965f3cc721b58731ddea7 Mon Sep 17 00:00:00 2001 From: Scott Marquis Date: Wed, 29 Apr 2020 09:06:49 +0100 Subject: [PATCH 15/15] #912 fixed a flake8 issue --- pybamm/models/full_battery_models/base_battery_model.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pybamm/models/full_battery_models/base_battery_model.py b/pybamm/models/full_battery_models/base_battery_model.py index 6aa5caf626..606142a5c4 100644 --- a/pybamm/models/full_battery_models/base_battery_model.py +++ b/pybamm/models/full_battery_models/base_battery_model.py @@ -242,7 +242,8 @@ def options(self, extra_options): if options["thermal"] == "x-lumped" and options["dimensionality"] == 1: warnings.warn( - "1+1D Thermal models are only valid if both tabs are places at the top of the cell." + "1+1D Thermal models are only valid if both tabs are" + + "placed at the top of the cell." ) self._options = options