Repository: pybamm-team/PyBaMM

Issue:
lumped thermal model with half cell
Using a lumped thermal model with half cell gives an error because the options aren't passed to thermal models (so they don't know it's a half cell)

```python3
import pybamm

model = pybamm.lithium_ion.DFN(
    options={
        "working electrode": "positive",
        "thermal": "lumped",
    }
)
```

gives 

```
DomainError: Functions can only be applied to variables on the same domain
```


Discussion:

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e27a64f5f..a249fe752 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,10 +1,14 @@
 # [Unreleased](https://github.com/pybamm-team/PyBaMM/)
 
-
 ## Features
 
+-   Isothermal models now compute heat source terms (but the temperature remains constant). The models now also account for current collector heating when `dimensionality=0` [#1929](https://github.com/pybamm-team/PyBaMM/pull/1929))
 -   Initial concentrations can now be provided as a function of `r` as well as `x` ([#1866](https://github.com/pybamm-team/PyBaMM/pull/1866))
 
+## Bug fixes
+
+-   Fixed a bug where thermal submodels could not be used with half-cells ([#1929](https://github.com/pybamm-team/PyBaMM/pull/1929))
+
 ## Breaking changes
 
 -   The `domain` setter and `auxiliary_domains` getter have been deprecated, `domains` setter/getter should be used instead. The `domain` getter is still active. We now recommend creating symbols with `domains={...}` instead of `domain=..., auxiliary_domains={...}`, but the latter is not yet deprecated ([#1866](https://github.com/pybamm-team/PyBaMM/pull/1866))
diff --git a/pybamm/models/full_battery_models/base_battery_model.py b/pybamm/models/full_battery_models/base_battery_model.py
index 14e7cd9c2..95e1c1291 100644
--- a/pybamm/models/full_battery_models/base_battery_model.py
+++ b/pybamm/models/full_battery_models/base_battery_model.py
@@ -362,6 +362,13 @@ class BatteryModelOptions(pybamm.FuzzyDict):
                     "cannot have transverse convection in 0D model"
                 )
 
+        if (
+            options["thermal"] in ["x-lumped", "x-full"]
+            and options["cell geometry"] != "pouch"
+        ):
+            raise pybamm.OptionError(
+                options["thermal"] + " model must have pouch geometry."
+            )
         if options["thermal"] == "x-full" and options["dimensionality"] != 0:
             n = options["dimensionality"]
             raise pybamm.OptionError(
@@ -378,6 +385,18 @@ class BatteryModelOptions(pybamm.FuzzyDict):
                     "mechanics model"
                 )
 
+        if options["working electrode"] != "both":
+            if options["thermal"] == "x-full":
+                raise pybamm.OptionError(
+                    "X-full thermal submodel is not compatible with half-cell models"
+                )
+            elif options["thermal"] == "x-lumped" and options["dimensionality"] != 0:
+                n = options["dimensionality"]
+                raise pybamm.OptionError(
+                    f"X-lumped thermal submodels do not yet support {n}D "
+                    "current collectors in a half-cell configuration"
+                )
+
         # Check options are valid
         for option, value in options.items():
             if option == "external submodels" or option == "working electrode":
@@ -578,13 +597,6 @@ class BaseBatteryModel(pybamm.BaseModel):
                 raise pybamm.OptionError(
                     "convection not implemented for lithium-ion models"
                 )
-            if (
-                options["thermal"] in ["x-lumped", "x-full"]
-                and options["cell geometry"] != "pouch"
-            ):
-                raise pybamm.OptionError(
-                    options["thermal"] + " model must have pouch geometry."
-                )
         if isinstance(self, pybamm.lithium_ion.SPMe):
             if options["electrolyte conductivity"] not in [
                 "default",
@@ -925,25 +937,27 @@ class BaseBatteryModel(pybamm.BaseModel):
         elif self.options["thermal"] == "lumped":
             thermal_submodel = pybamm.thermal.Lumped(
                 self.param,
-                cc_dimension=self.options["dimensionality"],
-                geometry=self.options["cell geometry"],
+                self.options,
             )
 
         elif self.options["thermal"] == "x-lumped":
             if self.options["dimensionality"] == 0:
-                # With 0D current collectors x-lumped is equivalent to lumped pouch
-                thermal_submodel = pybamm.thermal.Lumped(self.param, geometry="pouch")
+                thermal_submodel = pybamm.thermal.Lumped(self.param, self.options)
             elif self.options["dimensionality"] == 1:
                 thermal_submodel = pybamm.thermal.pouch_cell.CurrentCollector1D(
-                    self.param
+                    self.param,
+                    self.options,
                 )
             elif self.options["dimensionality"] == 2:
                 thermal_submodel = pybamm.thermal.pouch_cell.CurrentCollector2D(
-                    self.param
+                    self.param,
+                    self.options,
                 )
         elif self.options["thermal"] == "x-full":
             if self.options["dimensionality"] == 0:
-                thermal_submodel = pybamm.thermal.OneDimensionalX(self.param)
+                thermal_submodel = pybamm.thermal.OneDimensionalX(
+                    self.param, self.options
+                )
 
         self.submodels["thermal"] = thermal_submodel
 
diff --git a/pybamm/models/submodels/current_collector/effective_resistance_current_collector.py b/pybamm/models/submodels/current_collector/effective_resistance_current_collector.py
index 6de02c538..661467378 100644
--- a/pybamm/models/submodels/current_collector/effective_resistance_current_collector.py
+++ b/pybamm/models/submodels/current_collector/effective_resistance_current_collector.py
@@ -114,7 +114,8 @@ class EffectiveResistance(BaseEffectiveResistance):
     References
     ----------
     .. [1] R Timms, SG Marquis, V Sulzer, CP Please and SJ Chapman. “Asymptotic
-           Reduction of a Lithium-ion Pouch Cell Model”. Submitted, 2020.
+           Reduction of a Lithium-ion Pouch Cell Model”. SIAM Journal on Applied
+           Mathematics, 81(3), 765--788, 2021
 
     **Extends:** :class:`BaseEffectiveResistance`
     """
@@ -123,6 +124,9 @@ class EffectiveResistance(BaseEffectiveResistance):
         self, options=None, name="Effective resistance in current collector model"
     ):
         super().__init__(name)
+
+        pybamm.citations.register("Timms2021")
+
         self.options = options
         self.param = pybamm.LithiumIonParameters()
 
diff --git a/pybamm/models/submodels/current_collector/potential_pair.py b/pybamm/models/submodels/current_collector/potential_pair.py
index 4f7f0efdc..36fedaa9c 100644
--- a/pybamm/models/submodels/current_collector/potential_pair.py
+++ b/pybamm/models/submodels/current_collector/potential_pair.py
@@ -17,10 +17,11 @@ class BasePotentialPair(BaseModel):
     References
     ----------
     .. [1] R Timms, SG Marquis, V Sulzer, CP Please and SJ Chapman. “Asymptotic
-           Reduction of a Lithium-ion Pouch Cell Model”. Submitted, 2020.
+           Reduction of a Lithium-ion Pouch Cell Model”. SIAM Journal on Applied
+           Mathematics, 81(3), 765--788, 2021
     .. [2] SG Marquis, R Timms, V Sulzer, CP Please and SJ Chapman. “A Suite of
-           Reduced-Order Models of a Single-Layer Lithium-ion Pouch Cell”. In
-           preparation, 2020.
+           Reduced-Order Models of a Single-Layer Lithium-ion Pouch Cell”. Journal
+           of The Electrochemical Society, 167(14):140513, 2020
 
     **Extends:** :class:`pybamm.current_collector.BaseModel`
     """
diff --git a/pybamm/models/submodels/thermal/base_thermal.py b/pybamm/models/submodels/thermal/base_thermal.py
index 15393c671..db81b4de0 100644
--- a/pybamm/models/submodels/thermal/base_thermal.py
+++ b/pybamm/models/submodels/thermal/base_thermal.py
@@ -5,7 +5,8 @@ import pybamm
 
 
 class BaseThermal(pybamm.BaseSubModel):
-    """Base class for thermal effects
+    """
+    Base class for thermal effects
 
     Parameters
     ----------
@@ -13,14 +14,11 @@ class BaseThermal(pybamm.BaseSubModel):
         The parameters to use for this submodel
     options : dict, optional
         A dictionary of options to be passed to the model.
-    cc_dimension: int, optional
-        The dimension of the current collectors. Can be 0 (default), 1 or 2.
 
     **Extends:** :class:`pybamm.BaseSubModel`
     """
 
-    def __init__(self, param, options=None, cc_dimension=0):
-        self.cc_dimension = cc_dimension
+    def __init__(self, param, options=None):
         super().__init__(param, options=options)
 
     def _get_standard_fundamental_variables(
@@ -29,7 +27,7 @@ class BaseThermal(pybamm.BaseSubModel):
         """
         Note: here we explicitly pass in the averages for the temperature as computing
         the average temperature in `BaseThermal` using `self._x_average` requires a
-        messy hack to avoid raising a `ModelError` (as the key in the equation
+        workaround to avoid raising a `ModelError` (as the key in the equation
         dict gets modified).
 
         For more information about this method in general,
@@ -38,7 +36,7 @@ class BaseThermal(pybamm.BaseSubModel):
         param = self.param
 
         # The variable T is the concatenation of the temperature in the negative
-        # electrode, separator and positive electrode, for use the electrochemical
+        # electrode, separator and positive electrode, for use in the electrochemical
         # models
         T = pybamm.concatenation(T_n, T_s, T_p)
 
@@ -90,38 +88,21 @@ class BaseThermal(pybamm.BaseSubModel):
         return variables
 
     def _get_standard_coupled_variables(self, variables):
-
         param = self.param
 
-        T_n = variables["Negative electrode temperature"]
-        T_p = variables["Positive electrode temperature"]
-
-        a_n = variables["Negative electrode surface area to volume ratio"]
-        a_p = variables["Positive electrode surface area to volume ratio"]
-
-        j_n = variables["Negative electrode interfacial current density"]
-        j_p = variables["Positive electrode interfacial current density"]
-
-        eta_r_n = variables["Negative electrode reaction overpotential"]
-        eta_r_p = variables["Positive electrode reaction overpotential"]
-
-        dUdT_n = variables["Negative electrode entropic change"]
-        dUdT_p = variables["Positive electrode entropic change"]
-
-        i_e = variables["Electrolyte current density"]
-        phi_e = variables["Electrolyte potential"]
-        phi_e_n = variables["Negative electrolyte potential"]
-        phi_e_s = variables["Separator electrolyte potential"]
-        phi_e_p = variables["Positive electrolyte potential"]
-
-        i_s_n = variables["Negative electrode current density"]
+        # Ohmic heating in solid
         i_s_p = variables["Positive electrode current density"]
-        phi_s_n = variables["Negative electrode potential"]
         phi_s_p = variables["Positive electrode potential"]
-
-        # Ohmic heating in solid
         Q_ohm_s_cn, Q_ohm_s_cp = self._current_collector_heating(variables)
-        Q_ohm_s_n = -pybamm.inner(i_s_n, pybamm.grad(phi_s_n))
+        if self.half_cell:
+            i_boundary_cc = variables["Current collector current density"]
+            T_n = variables["Negative electrode temperature"]
+            Q_ohm_s_n_av = i_boundary_cc ** 2 / param.sigma_n(T_n)
+            Q_ohm_s_n = pybamm.PrimaryBroadcast(Q_ohm_s_n_av, "negative electrode")
+        else:
+            i_s_n = variables["Negative electrode current density"]
+            phi_s_n = variables["Negative electrode potential"]
+            Q_ohm_s_n = -pybamm.inner(i_s_n, pybamm.grad(phi_s_n))
         Q_ohm_s_s = pybamm.FullBroadcast(0, ["separator"], "current collector")
         Q_ohm_s_p = -pybamm.inner(i_s_p, pybamm.grad(phi_s_p))
         Q_ohm_s = pybamm.concatenation(Q_ohm_s_n, Q_ohm_s_s, Q_ohm_s_p)
@@ -129,21 +110,51 @@ class BaseThermal(pybamm.BaseSubModel):
         # Ohmic heating in electrolyte
         # TODO: change full stefan-maxwell conductivity so that i_e is always
         # a Concatenation
+        i_e = variables["Electrolyte current density"]
+        phi_e = variables["Electrolyte potential"]
         if isinstance(i_e, pybamm.Concatenation):
             # compute by domain if possible
-            i_e_n, i_e_s, i_e_p = i_e.orphans
-            Q_ohm_e_n = -pybamm.inner(i_e_n, pybamm.grad(phi_e_n))
+            phi_e_s = variables["Separator electrolyte potential"]
+            phi_e_p = variables["Positive electrolyte potential"]
+            if self.half_cell:
+                i_e_s, i_e_p = i_e.orphans
+                Q_ohm_e_n = pybamm.FullBroadcast(
+                    0, ["negative electrode"], "current collector"
+                )
+            else:
+                i_e_n, i_e_s, i_e_p = i_e.orphans
+                phi_e_n = variables["Negative electrolyte potential"]
+                Q_ohm_e_n = -pybamm.inner(i_e_n, pybamm.grad(phi_e_n))
             Q_ohm_e_s = -pybamm.inner(i_e_s, pybamm.grad(phi_e_s))
             Q_ohm_e_p = -pybamm.inner(i_e_p, pybamm.grad(phi_e_p))
             Q_ohm_e = pybamm.concatenation(Q_ohm_e_n, Q_ohm_e_s, Q_ohm_e_p)
         else:
-            Q_ohm_e = -pybamm.inner(i_e, pybamm.grad(phi_e))
+            # else compute using i_e across all domains
+            if self.half_cell:
+                Q_ohm_e_n = pybamm.FullBroadcast(
+                    0, ["negative electrode"], "current collector"
+                )
+                Q_ohm_e_s_p = -pybamm.inner(i_e, pybamm.grad(phi_e))
+                Q_ohm_e = pybamm.concatenation(Q_ohm_e_n, Q_ohm_e_s_p)
+            else:
+                Q_ohm_e = -pybamm.inner(i_e, pybamm.grad(phi_e))
 
         # Total Ohmic heating
         Q_ohm = Q_ohm_s + Q_ohm_e
 
         # Irreversible electrochemical heating
-        Q_rxn_n = a_n * j_n * eta_r_n
+        a_p = variables["Positive electrode surface area to volume ratio"]
+        j_p = variables["Positive electrode interfacial current density"]
+        eta_r_p = variables["Positive electrode reaction overpotential"]
+        if self.half_cell:
+            Q_rxn_n = pybamm.FullBroadcast(
+                0, ["negative electrode"], "current collector"
+            )
+        else:
+            a_n = variables["Negative electrode surface area to volume ratio"]
+            j_n = variables["Negative electrode interfacial current density"]
+            eta_r_n = variables["Negative electrode reaction overpotential"]
+            Q_rxn_n = a_n * j_n * eta_r_n
         Q_rxn_p = a_p * j_p * eta_r_p
         Q_rxn = pybamm.concatenation(
             *[
@@ -154,7 +165,16 @@ class BaseThermal(pybamm.BaseSubModel):
         )
 
         # Reversible electrochemical heating
-        Q_rev_n = a_n * j_n * (param.Theta ** (-1) + T_n) * dUdT_n
+        T_p = variables["Positive electrode temperature"]
+        dUdT_p = variables["Positive electrode entropic change"]
+        if self.half_cell:
+            Q_rev_n = pybamm.FullBroadcast(
+                0, ["negative electrode"], "current collector"
+            )
+        else:
+            T_n = variables["Negative electrode temperature"]
+            dUdT_n = variables["Negative electrode entropic change"]
+            Q_rev_n = a_n * j_n * (param.Theta ** (-1) + T_n) * dUdT_n
         Q_rev_p = a_p * j_p * (param.Theta ** (-1) + T_p) * dUdT_p
         Q_rev = pybamm.concatenation(
             *[
@@ -216,28 +236,29 @@ class BaseThermal(pybamm.BaseSubModel):
 
     def _current_collector_heating(self, variables):
         """Compute Ohmic heating in current collectors."""
-        # TODO: implement grad in 0D to return a scalar zero
-        # TODO: implement grad_squared in other spatial methods so that the if
-        # statement can be removed
-        # In the limit of infinitely large current collector conductivity (i.e.
-        # 0D current collectors), the Ohmic heating in the current collectors is
-        # zero
+        cc_dimension = self.options["dimensionality"]
 
-        if self.cc_dimension == 0:
-            Q_s_cn = pybamm.Scalar(0)
-            Q_s_cp = pybamm.Scalar(0)
+        # Compute the Ohmic heating for 0D current collectors
+        if cc_dimension == 0:
+            i_boundary_cc = variables["Current collector current density"]
+            Q_s_cn = i_boundary_cc ** 2 / self.param.sigma_cn
+            Q_s_cp = i_boundary_cc ** 2 / self.param.sigma_cp
         # Otherwise we compute the Ohmic heating for 1 or 2D current collectors
-        elif self.cc_dimension in [1, 2]:
+        # In this limit the current flow is all in the y,z direction in the current
+        # collectors
+        elif cc_dimension in [1, 2]:
             phi_s_cn = variables["Negative current collector potential"]
             phi_s_cp = variables["Positive current collector potential"]
-            if self.cc_dimension == 1:
+            # TODO: implement grad_squared in other spatial methods so that the
+            # if statement can be removed
+            if cc_dimension == 1:
                 Q_s_cn = self.param.sigma_cn_prime * pybamm.inner(
                     pybamm.grad(phi_s_cn), pybamm.grad(phi_s_cn)
                 )
                 Q_s_cp = self.param.sigma_cp_prime * pybamm.inner(
                     pybamm.grad(phi_s_cp), pybamm.grad(phi_s_cp)
                 )
-            elif self.cc_dimension == 2:
+            elif cc_dimension == 2:
                 # Inner not implemented in 2D -- have to call grad_squared directly
                 Q_s_cn = self.param.sigma_cn_prime * pybamm.grad_squared(phi_s_cn)
                 Q_s_cp = self.param.sigma_cp_prime * pybamm.grad_squared(phi_s_cp)
@@ -266,7 +287,7 @@ class BaseThermal(pybamm.BaseSubModel):
         """Computes the y-z average."""
         # TODO: change the behaviour of z_average and yz_average so the if statement
         # can be removed
-        if self.cc_dimension in [0, 1]:
+        if self.options["dimensionality"] in [0, 1]:
             return pybamm.z_average(var)
-        elif self.cc_dimension == 2:
+        elif self.options["dimensionality"] == 2:
             return pybamm.yz_average(var)
diff --git a/pybamm/models/submodels/thermal/isothermal.py b/pybamm/models/submodels/thermal/isothermal.py
index 250e8abf0..d620c8f38 100644
--- a/pybamm/models/submodels/thermal/isothermal.py
+++ b/pybamm/models/submodels/thermal/isothermal.py
@@ -7,7 +7,8 @@ from .base_thermal import BaseThermal
 
 
 class Isothermal(BaseThermal):
-    """Class for isothermal submodel.
+    """
+    Class for isothermal submodel.
 
     Parameters
     ----------
@@ -26,50 +27,18 @@ class Isothermal(BaseThermal):
         T_amb = self.param.T_amb(pybamm.t * self.param.timescale)
         T_x_av = pybamm.PrimaryBroadcast(T_amb, "current collector")
         T_vol_av = pybamm.PrimaryBroadcast(T_amb, "current collector")
-        T_s = pybamm.PrimaryBroadcast(T_x_av, "separator")
-        T_p = pybamm.PrimaryBroadcast(T_x_av, "positive electrode")
-        T_cp = T_x_av
-        T_cn = T_x_av
 
+        T_cn = T_x_av
         if self.half_cell:
             T_n = None
         else:
             T_n = pybamm.PrimaryBroadcast(T_x_av, "negative electrode")
+        T_s = pybamm.PrimaryBroadcast(T_x_av, "separator")
+        T_p = pybamm.PrimaryBroadcast(T_x_av, "positive electrode")
+        T_cp = T_x_av
 
         variables = self._get_standard_fundamental_variables(
             T_cn, T_n, T_s, T_p, T_cp, T_x_av, T_vol_av
         )
 
         return variables
-
-    def get_coupled_variables(self, variables):
-        ieh = "irreversible electrochemical heating"
-        variables.update(
-            {
-                "Ohmic heating": pybamm.Scalar(0),
-                "Ohmic heating [W.m-3]": pybamm.Scalar(0),
-                "X-averaged Ohmic heating": pybamm.Scalar(0),
-                "X-averaged Ohmic heating [W.m-3]": pybamm.Scalar(0),
-                "Volume-averaged Ohmic heating": pybamm.Scalar(0),
-                "Volume-averaged Ohmic heating [W.m-3]": pybamm.Scalar(0),
-                "Irreversible electrochemical heating": pybamm.Scalar(0),
-                "Irreversible electrochemical heating [W.m-3]": pybamm.Scalar(0),
-                "X-averaged " + ieh: pybamm.Scalar(0),
-                "X-averaged " + ieh + " [W.m-3]": pybamm.Scalar(0),
-                "Volume-averaged " + ieh: pybamm.Scalar(0),
-                "Volume-averaged " + ieh + "[W.m-3]": pybamm.Scalar(0),
-                "Reversible heating": pybamm.Scalar(0),
-                "Reversible heating [W.m-3]": pybamm.Scalar(0),
-                "X-averaged reversible heating": pybamm.Scalar(0),
-                "X-averaged reversible heating [W.m-3]": pybamm.Scalar(0),
-                "Volume-averaged reversible heating": pybamm.Scalar(0),
-                "Volume-averaged reversible heating [W.m-3]": pybamm.Scalar(0),
-                "Total heating": pybamm.Scalar(0),
-                "Total heating [W.m-3]": pybamm.Scalar(0),
-                "X-averaged total heating": pybamm.Scalar(0),
-                "X-averaged total heating [W.m-3]": pybamm.Scalar(0),
-                "Volume-averaged total heating": pybamm.Scalar(0),
-                "Volume-averaged total heating [W.m-3]": pybamm.Scalar(0),
-            }
-        )
-        return variables
diff --git a/pybamm/models/submodels/thermal/lumped.py b/pybamm/models/submodels/thermal/lumped.py
index b0f11d4b9..ed665b299 100644
--- a/pybamm/models/submodels/thermal/lumped.py
+++ b/pybamm/models/submodels/thermal/lumped.py
@@ -7,29 +7,30 @@ from .base_thermal import BaseThermal
 
 
 class Lumped(BaseThermal):
-    """Class for lumped thermal submodel. For more information see [1]_.
+    """
+    Class for lumped thermal submodel. For more information see [1]_ and [2]_.
 
     Parameters
     ----------
     param : parameter class
         The parameters to use for this submodel
-    cc_dimension: int, optional
-        The dimension of the current collectors. Can be 0 (default), 1 or 2.
-    geometry: string, optional
-        The geometry for the lumped thermal submodel. Can be "arbitrary" (default) or
-        pouch.
+    options : dict, optional
+        A dictionary of options to be passed to the model.
 
     References
     ----------
     .. [1] R Timms, SG Marquis, V Sulzer, CP Please and SJ Chapman. “Asymptotic
-           Reduction of a Lithium-ion Pouch Cell Model”. In preparation, 2020.
+           Reduction of a Lithium-ion Pouch Cell Model”. SIAM Journal on Applied
+           Mathematics, 81(3), 765--788, 2021
+    .. [2] SG Marquis, R Timms, V Sulzer, CP Please and SJ Chapman. “A Suite of
+           Reduced-Order Models of a Single-Layer Lithium-ion Pouch Cell”. Journal
+           of The Electrochemical Society, 167(14):140513, 2020
 
     **Extends:** :class:`pybamm.thermal.BaseThermal`
     """
 
-    def __init__(self, param, cc_dimension=0, geometry="arbitrary"):
-        self.geometry = geometry
-        super().__init__(param, cc_dimension=cc_dimension)
+    def __init__(self, param, options=None):
+        super().__init__(param, options=options)
         pybamm.citations.register("Timms2021")
 
     def get_fundamental_variables(self):
@@ -38,7 +39,10 @@ class Lumped(BaseThermal):
         T_x_av = pybamm.PrimaryBroadcast(T_vol_av, ["current collector"])
 
         T_cn = T_x_av
-        T_n = pybamm.PrimaryBroadcast(T_x_av, "negative electrode")
+        if self.half_cell:
+            T_n = None
+        else:
+            T_n = pybamm.PrimaryBroadcast(T_x_av, "negative electrode")
         T_s = pybamm.PrimaryBroadcast(T_x_av, "separator")
         T_p = pybamm.PrimaryBroadcast(T_x_av, "positive electrode")
         T_cp = T_x_av
@@ -60,7 +64,7 @@ class Lumped(BaseThermal):
 
         # Account for surface area to volume ratio in cooling coefficient
         # The factor 1/delta^2 comes from the choice of non-dimensionalisation.
-        if self.geometry == "pouch":
+        if self.options["cell geometry"] == "pouch":
             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
@@ -97,7 +101,7 @@ class Lumped(BaseThermal):
                 + positive_tab_cooling_coefficient
                 + edge_cooling_coefficient
             )
-        elif self.geometry == "arbitrary":
+        elif self.options["cell geometry"] == "arbitrary":
             cell_surface_area = self.param.a_cooling
             cell_volume = self.param.v_cell
             total_cooling_coefficient = (
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 0e5a7c46f..365250746 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
@@ -16,20 +16,23 @@ class CurrentCollector1D(BaseThermal):
     ----------
     param : parameter class
         The parameters to use for this submodel
+    options : dict, optional
+        A dictionary of options to be passed to the model.
 
     References
     ----------
     .. [1] R Timms, SG Marquis, V Sulzer, CP Please and SJ Chapman. “Asymptotic
-           Reduction of a Lithium-ion Pouch Cell Model”. In preparation, 2020.
+           Reduction of a Lithium-ion Pouch Cell Model”. SIAM Journal on Applied
+           Mathematics, 81(3), 765--788, 2021
     .. [2] SG Marquis, R Timms, V Sulzer, CP Please and SJ Chapman. “A Suite of
-           Reduced-Order Models of a Single-Layer Lithium-ion Pouch Cell”. In
-           preparation, 2020.
+           Reduced-Order Models of a Single-Layer Lithium-ion Pouch Cell”. Journal
+           of The Electrochemical Society, 167(14):140513, 2020
 
     **Extends:** :class:`pybamm.thermal.BaseThermal`
     """
 
-    def __init__(self, param):
-        super().__init__(param, cc_dimension=1)
+    def __init__(self, param, options=None):
+        super().__init__(param, options=options)
         pybamm.citations.register("Timms2021")
 
     def get_fundamental_variables(self):
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 8fbad6460..ce9442fcd 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
@@ -16,20 +16,23 @@ class CurrentCollector2D(BaseThermal):
     ----------
     param : parameter class
         The parameters to use for this submodel
+    options : dict, optional
+        A dictionary of options to be passed to the model.
 
     References
     ----------
     .. [1] R Timms, SG Marquis, V Sulzer, CP Please and SJ Chapman. “Asymptotic
-           Reduction of a Lithium-ion Pouch Cell Model”. In preparation, 2020.
+           Reduction of a Lithium-ion Pouch Cell Model”. SIAM Journal on Applied
+           Mathematics, 81(3), 765--788, 2021
     .. [2] SG Marquis, R Timms, V Sulzer, CP Please and SJ Chapman. “A Suite of
-           Reduced-Order Models of a Single-Layer Lithium-ion Pouch Cell”. In
-           preparation, 2020.
+           Reduced-Order Models of a Single-Layer Lithium-ion Pouch Cell”. Journal
+           of The Electrochemical Society, 167(14):140513, 2020
 
     **Extends:** :class:`pybamm.thermal.BaseThermal`
     """
 
-    def __init__(self, param):
-        super().__init__(param, cc_dimension=2)
+    def __init__(self, param, options=None):
+        super().__init__(param, options=options)
         pybamm.citations.register("Timms2021")
 
     def get_fundamental_variables(self):
diff --git a/pybamm/models/submodels/thermal/x_full.py b/pybamm/models/submodels/thermal/x_full.py
index a3bf46652..2a8bbb563 100644
--- a/pybamm/models/submodels/thermal/x_full.py
+++ b/pybamm/models/submodels/thermal/x_full.py
@@ -7,28 +7,35 @@ from .base_thermal import BaseThermal
 
 
 class OneDimensionalX(BaseThermal):
-    """Class for one-dimensional (x-direction) thermal submodel.
+    """
+    Class for one-dimensional (x-direction) thermal submodel.
     Note: this model assumes infinitely large electrical and thermal conductivity
     in the current collectors, so that the contribution to the Ohmic heating
     from the current collectors is zero and the boundary conditions are applied
     at the edges of the electrodes (at x=0 and x=1, in non-dimensional coordinates).
-    For more information see [1]_.
+    For more information see [1]_ and [2]_.
 
     Parameters
     ----------
     param : parameter class
         The parameters to use for this submodel
+    options : dict, optional
+        A dictionary of options to be passed to the model.
 
     References
     ----------
     .. [1] R Timms, SG Marquis, V Sulzer, CP Please and SJ Chapman. “Asymptotic
-           Reduction of a Lithium-ion Pouch Cell Model”. In preparation, 2020.
+           Reduction of a Lithium-ion Pouch Cell Model”. SIAM Journal on Applied
+           Mathematics, 81(3), 765--788, 2021
+    .. [2] SG Marquis, R Timms, V Sulzer, CP Please and SJ Chapman. “A Suite of
+           Reduced-Order Models of a Single-Layer Lithium-ion Pouch Cell”. Journal
+           of The Electrochemical Society, 167(14):140513, 2020
 
     **Extends:** :class:`pybamm.thermal.BaseThermal`
     """
 
-    def __init__(self, param):
-        super().__init__(param)
+    def __init__(self, param, options=None):
+        super().__init__(param, options=options)
         pybamm.citations.register("Timms2021")
 
     def get_fundamental_variables(self):


Test patch:
diff --git a/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_mpm.py b/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_mpm.py
index 0f040924e..188a50851 100644
--- a/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_mpm.py
+++ b/tests/integration/test_models/test_full_battery_models/test_lithium_ion/test_mpm.py
@@ -84,8 +84,6 @@ if __name__ == "__main__":
     print("Add -v for more debug output")
     import sys
 
-    sys.setrecursionlimit(10000)
-
     if "-v" in sys.argv:
         debug = True
     unittest.main()
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 5be748996..5b58e4622 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
@@ -86,8 +86,6 @@ if __name__ == "__main__":
     print("Add -v for more debug output")
     import sys
 
-    sys.setrecursionlimit(10000)
-
     if "-v" in sys.argv:
         debug = True
     pybamm.settings.debug_mode = True
diff --git a/tests/unit/test_models/test_full_battery_models/test_base_battery_model.py b/tests/unit/test_models/test_full_battery_models/test_base_battery_model.py
index e06eb35ed..73fe28b9d 100644
--- a/tests/unit/test_models/test_full_battery_models/test_base_battery_model.py
+++ b/tests/unit/test_models/test_full_battery_models/test_base_battery_model.py
@@ -294,6 +294,26 @@ class TestBaseBatteryModel(unittest.TestCase):
         with self.assertRaisesRegex(pybamm.OptionError, "timescale"):
             pybamm.BaseBatteryModel({"timescale": "bad timescale"})
 
+        # thermal x-lumped
+        with self.assertRaisesRegex(pybamm.OptionError, "x-lumped"):
+            pybamm.lithium_ion.BaseModel(
+                {"cell geometry": "arbitrary", "thermal": "x-lumped"}
+            )
+
+        # thermal half-cell
+        with self.assertRaisesRegex(pybamm.OptionError, "X-full"):
+            pybamm.BaseBatteryModel(
+                {"thermal": "x-full", "working electrode": "positive"}
+            )
+        with self.assertRaisesRegex(pybamm.OptionError, "X-lumped"):
+            pybamm.BaseBatteryModel(
+                {
+                    "dimensionality": 2,
+                    "thermal": "x-lumped",
+                    "working electrode": "positive",
+                }
+            )
+
     def test_build_twice(self):
         model = pybamm.lithium_ion.SPM()  # need to pick a model to set vars and build
         with self.assertRaisesRegex(pybamm.ModelError, "Model already built"):
diff --git a/tests/unit/test_models/test_full_battery_models/test_lithium_ion/base_lithium_ion_half_cell_tests.py b/tests/unit/test_models/test_full_battery_models/test_lithium_ion/base_lithium_ion_half_cell_tests.py
index 0ee99805b..1635c2ea4 100644
--- a/tests/unit/test_models/test_full_battery_models/test_lithium_ion/base_lithium_ion_half_cell_tests.py
+++ b/tests/unit/test_models/test_full_battery_models/test_lithium_ion/base_lithium_ion_half_cell_tests.py
@@ -70,3 +70,7 @@ class BaseUnitTestLithiumIonHalfCell:
     def test_well_posed_ec_reaction_limited_sei(self):
         options = {"SEI": "ec reaction limited"}
         self.check_well_posedness(options)
+
+    def test_well_posed_lumped_thermal(self):
+        options = {"thermal": "lumped"}
+        self.check_well_posedness(options)
diff --git a/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_base_lithium_ion_model.py b/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_base_lithium_ion_model.py
index a2360ee66..1eff88e4b 100644
--- a/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_base_lithium_ion_model.py
+++ b/tests/unit/test_models/test_full_battery_models/test_lithium_ion/test_base_lithium_ion_model.py
@@ -10,10 +10,6 @@ class TestBaseLithiumIonModel(unittest.TestCase):
     def test_incompatible_options(self):
         with self.assertRaisesRegex(pybamm.OptionError, "convection not implemented"):
             pybamm.lithium_ion.BaseModel({"convection": "uniform transverse"})
-        with self.assertRaisesRegex(pybamm.OptionError, "x-lumped"):
-            pybamm.lithium_ion.BaseModel(
-                {"cell geometry": "arbitrary", "thermal": "x-lumped"}
-            )
 
     def test_default_parameters(self):
         # check parameters are read in ok