diff --git a/docs/source/expression_tree/unary_operator.rst b/docs/source/expression_tree/unary_operator.rst
index 45b50e6b..6884637f 100644
--- a/docs/source/expression_tree/unary_operator.rst
+++ b/docs/source/expression_tree/unary_operator.rst
@@ -19,7 +19,7 @@ Unary Operators
 .. autoclass:: pybamm.Divergence
   :members:
 
-.. autoclass:: pybamm.SurfaceValue
+.. autoclass:: pybamm.BoundaryValue
   :members:
 
 .. autoclass:: pybamm.Integral
diff --git a/pybamm/__init__.py b/pybamm/__init__.py
index 464d9cb5..e294ff64 100644
--- a/pybamm/__init__.py
+++ b/pybamm/__init__.py
@@ -75,7 +75,7 @@ from .expression_tree.unary_operators import (
     SpatialOperator,
     Gradient,
     Divergence,
-    SurfaceValue,
+    BoundaryValue,
     Integral,
     grad,
     div,
diff --git a/pybamm/discretisations/discretisation.py b/pybamm/discretisations/discretisation.py
index b20b3694..bf7991a1 100644
--- a/pybamm/discretisations/discretisation.py
+++ b/pybamm/discretisations/discretisation.py
@@ -235,11 +235,11 @@ class Discretisation(object):
                 )
             return symbol
 
-        elif isinstance(symbol, pybamm.SurfaceValue):
+        elif isinstance(symbol, pybamm.BoundaryValue):
             child = symbol.children[0]
             discretised_child = self.process_symbol(child)
-            return self._spatial_methods[child.domain[0]].surface_value(
-                discretised_child
+            return self._spatial_methods[child.domain[0]].boundary_value(
+                discretised_child, symbol.side
             )
 
         elif isinstance(symbol, pybamm.BinaryOperator):
diff --git a/pybamm/expression_tree/unary_operators.py b/pybamm/expression_tree/unary_operators.py
index 4d12e5b2..a6ccb55e 100644
--- a/pybamm/expression_tree/unary_operators.py
+++ b/pybamm/expression_tree/unary_operators.py
@@ -207,17 +207,24 @@ class Integral(SpatialOperator):
         return self._integration_variable
 
 
-class SurfaceValue(SpatialOperator):
-    """A node in the expression tree which gets the surface value of a variable.
+class BoundaryValue(SpatialOperator):
+    """A node in the expression tree which gets the boundary value of a variable.
+
+    Parameters
+    ----------
+    child : `pybamm.Symbol`
+        The variable whose boundary value to take
+    side : string
+        Which side to take the boundary value on ("left" or "right")
 
     **Extends:** :class:`SpatialOperator`
     """
 
-    def __init__(self, child):
-        super().__init__("surf", child)
-
-        # Domain of SurfaceValue must be ([]) so that expressions can be formed
-        # of surface values of variables in different domains
+    def __init__(self, child, side):
+        super().__init__("boundary", child)
+        self.side = side
+        # Domain of BoundaryValue must be ([]) so that expressions can be formed
+        # of boundary values of variables in different domains
         self.domain = []
 
 
@@ -285,4 +292,4 @@ def surf(variable):
         the surface value of ``variable``
     """
 
-    return SurfaceValue(variable)
+    return BoundaryValue(variable, "right")
diff --git a/pybamm/parameters/parameter_values.py b/pybamm/parameters/parameter_values.py
index e00c226e..b3d66c27 100644
--- a/pybamm/parameters/parameter_values.py
+++ b/pybamm/parameters/parameter_values.py
@@ -179,6 +179,10 @@ class ParameterValues(dict):
             new_child = self.process_symbol(symbol.children[0])
             return pybamm.Integral(new_child, symbol.integration_variable)
 
+        elif isinstance(symbol, pybamm.BoundaryValue):
+            new_child = self.process_symbol(symbol.children[0])
+            return pybamm.BoundaryValue(new_child, symbol.side)
+
         elif isinstance(symbol, pybamm.UnaryOperator):
             new_child = self.process_symbol(symbol.children[0])
             return symbol.__class__(new_child)
diff --git a/pybamm/solvers/ode_solver.py b/pybamm/solvers/ode_solver.py
index be96eaef..46dc8609 100644
--- a/pybamm/solvers/ode_solver.py
+++ b/pybamm/solvers/ode_solver.py
@@ -45,6 +45,7 @@ class OdeSolver(pybamm.BaseSolver):
         events = [event_fun(event) for event in model.events]
 
         y0 = model.concatenated_initial_conditions
+
         self.t, self.y = self.integrate(dydt, y0, t_eval, events=events)
 
     def integrate(self, derivs, y0, t_eval, events=None):
diff --git a/pybamm/spatial_methods/finite_volume.py b/pybamm/spatial_methods/finite_volume.py
index 6714f70f..2352b69e 100644
--- a/pybamm/spatial_methods/finite_volume.py
+++ b/pybamm/spatial_methods/finite_volume.py
@@ -387,38 +387,38 @@ class FiniteVolume(pybamm.SpatialMethod):
 
         return new_discretised_symbol
 
-    def surface_value(self, discretised_symbol):
+    def boundary_value(self, discretised_symbol, side):
         """
-        Uses linear extrapolation to get the surface value of a variable in the
+        Uses linear extrapolation to get the boundary value of a variable in the
         Finite Volume Method.
 
         Parameters
         -----------
         discretised_symbol : :class:`pybamm.StateVector`
-            The discretised variable (a state vector) from which to calculate
-            the surface value.
+            The discretised variable from which to calculate the boundary value
+        side : string
+            Which side to take the boundary value on ("left" or "right")
 
         Returns
         -------
-        :class:`pybamm.Variable`
-            The variable representing the surface value.
+        :class:`pybamm.Symbol`
+            The variable representing the boundary value.
         """
-        # Better to make class similar NodeToEdge and pass function?
-        # def surface_value(array):
-        #     "Linear extrapolation for surface value"
-        #     array[-1] + (array[-1] - array[-2]) / 2
-        # ... or make StateVector and add?
-        y_slice_stop = discretised_symbol.y_slice.stop
-        last_node = pybamm.StateVector(slice(y_slice_stop - 1, y_slice_stop))
-        penultimate_node = pybamm.StateVector(slice(y_slice_stop - 2, y_slice_stop - 1))
-        surface_value = last_node + (last_node - penultimate_node) / 2
-        return surface_value
+
+        def linear_extrapolation(array):
+            """Linearly extrapolates an array"""
+            if side == "left":
+                return array[0] + (array[0] - array[1]) / 2
+            elif side == "right":
+                return array[-1] + (array[-1] - array[-2]) / 2
+
+        return BoundaryValueEvaluated(discretised_symbol, linear_extrapolation)
 
     #######################################################
     # Can probably be moved outside of the spatial method
     ######################################################
 
-    def compute_diffusivity(self, symbol):
+    def compute_diffusivity(self, discretised_symbol):
         """
         Compute the diffusivity at cell edges, based on the diffusivity at cell nodes.
         For now we just take the arithemtic mean, though it may be better to take the
@@ -429,7 +429,7 @@ class FiniteVolume(pybamm.SpatialMethod):
 
         Parameters
         ----------
-        symbol : :class:`pybamm.Symbol`
+        discretised_symbol : :class:`pybamm.Symbol`
             Symbol to be averaged. When evaluated, this symbol returns either a scalar
             or an array of shape (n,), where n is the number of points in the mesh for
             the symbol's domain (n = self.mesh[symbol.domain].npts)
@@ -445,7 +445,37 @@ class FiniteVolume(pybamm.SpatialMethod):
             """Calculate the arithemetic mean of an array"""
             return (array[1:] + array[:-1]) / 2
 
-        return pybamm.NodeToEdge(symbol, arithmetic_mean)
+        return pybamm.NodeToEdge(discretised_symbol, arithmetic_mean)
+
+
+class BoundaryValueEvaluated(pybamm.SpatialOperator):
+    """A node in the expression tree representing a unary operator that evaluates the
+    value of its child at a boundary.
+
+    Parameters
+    ----------
+    child : :class:`Symbol`
+        child node
+    boundary_function : method
+        the function used to calculate the boundary value
+
+    **Extends:** :class:`pybamm.SpatialOperator`
+    """
+
+    def __init__(self, child, boundary_function):
+        """ See :meth:`pybamm.UnaryOperator.__init__()`. """
+        super().__init__(
+            "boundary value ({})".format(boundary_function.__name__), child
+        )
+        self._boundary_function = boundary_function
+        # Domain of BoundaryValue must be ([]) so that expressions can be formed
+        # of boundary values of variables in different domains
+        self.domain = []
+
+    def evaluate(self, t=None, y=None):
+        """ See :meth:`pybamm.Symbol.evaluate()`. """
+        evaluated_child = self.children[0].evaluate(t, y)
+        return self._boundary_function(evaluated_child)
 
 
 class NodeToEdge(pybamm.SpatialOperator):
@@ -455,8 +485,6 @@ class NodeToEdge(pybamm.SpatialOperator):
     Parameters
     ----------
 
-    name : str
-        name of the node
     child : :class:`Symbol`
         child node
     node_to_edge_function : method
@@ -478,7 +506,6 @@ class NodeToEdge(pybamm.SpatialOperator):
         evaluated_child = self.children[0].evaluate(t, y)
         # If the evaluated child is a numpy array of shape (n,), do the averaging
         # NOTE: Doing this check every time might be slow?
-        # NOTE: Will need to deal with 2D arrays at some point
         if isinstance(evaluated_child, np.ndarray) and len(evaluated_child.shape) == 1:
             return self._node_to_edge_function(evaluated_child)
         # If not, no need to average

Evaluate "left" and "right"
Adapt `SurfaceValue` (from #159) to work with any object, not just `StateVector`, and to extrapolate at either end of the vector

**Motivation**
We need this to get the voltage from DFN 
diff --git a/tests/test_models/test_li_ion.py b/tests/test_models/test_li_ion.py
index dfe48abd..904ab6ae 100644
--- a/tests/test_models/test_li_ion.py
+++ b/tests/test_models/test_li_ion.py
@@ -17,7 +17,7 @@ class TestLiIonSPM(unittest.TestCase):
 
         modeltest.test_all()
 
-    def test_surface_concentrartion(self):
+    def test_surface_concentration(self):
         model = pybamm.li_ion.SPM()
         modeltest = tests.StandardModelTest(model)
         modeltest.test_all()
@@ -26,12 +26,12 @@ class TestLiIonSPM(unittest.TestCase):
         # check surface concentration decreases in negative particle and
         # increases in positive particle for discharge
         np.testing.assert_array_less(
-            model.variables["cn_surf"].evaluate(T, Y)[:, 1:],
-            model.variables["cn_surf"].evaluate(T, Y)[:, :-1],
+            model.variables["cn_surf"].evaluate(T, Y)[1:],
+            model.variables["cn_surf"].evaluate(T, Y)[:-1],
         )
         np.testing.assert_array_less(
-            model.variables["cp_surf"].evaluate(T, Y)[:, :-1],
-            model.variables["cp_surf"].evaluate(T, Y)[:, 1:],
+            model.variables["cp_surf"].evaluate(T, Y)[:-1],
+            model.variables["cp_surf"].evaluate(T, Y)[1:],
         )
         # test that surface concentrations are all positive
         np.testing.assert_array_less(0, model.variables["cn_surf"].evaluate(T, Y))
diff --git a/tests/test_spatial_methods/test_finite_volume.py b/tests/test_spatial_methods/test_finite_volume.py
index 42e92b14..17300738 100644
--- a/tests/test_spatial_methods/test_finite_volume.py
+++ b/tests/test_spatial_methods/test_finite_volume.py
@@ -32,14 +32,40 @@ class TestFiniteVolume(unittest.TestCase):
         avd = pybamm.NodeToEdge(d, arithmetic_mean)
         np.testing.assert_array_equal(avd.evaluate(None, y_test), np.ones(9))
 
-    def test_surface_value(self):
+    def test_extrapolate_left_right(self):
         # create discretisation
         mesh = get_mesh_for_testing()
-        spatial_methods = {"negative particle": pybamm.FiniteVolume}
+        spatial_methods = {
+            "macroscale": pybamm.FiniteVolume,
+            "negative particle": pybamm.FiniteVolume,
+        }
         disc = pybamm.Discretisation(mesh, spatial_methods)
 
-        combined_submesh = mesh.combine_submeshes("negative particle")
+        whole_cell = ["negative electrode", "separator", "positive electrode"]
+        macro_submesh = mesh.combine_submeshes(*whole_cell)
+        micro_submesh = mesh["negative particle"]
 
+        # Macroscale
+        # create variable
+        var = pybamm.Variable("var", domain=whole_cell)
+        # boundary value should work with something more complicated than a variable
+        extrap_left = pybamm.BoundaryValue(2 * var, "left")
+        extrap_right = pybamm.BoundaryValue(4 - var, "right")
+        disc.set_variable_slices([var])
+        extrap_left_disc = disc.process_symbol(extrap_left)
+        extrap_right_disc = disc.process_symbol(extrap_right)
+
+        # check constant extrapolates to constant
+        constant_y = np.ones_like(macro_submesh[0].nodes)
+        self.assertEqual(extrap_left_disc.evaluate(None, constant_y), 2)
+        self.assertEqual(extrap_right_disc.evaluate(None, constant_y), 3)
+
+        # check linear variable extrapolates correctly
+        linear_y = macro_submesh[0].nodes
+        self.assertEqual(extrap_left_disc.evaluate(None, linear_y), 0)
+        self.assertEqual(extrap_right_disc.evaluate(None, linear_y), 3)
+
+        # Microscale
         # create variable
         var = pybamm.Variable("var", domain="negative particle")
         surf_eqn = pybamm.surf(var)
@@ -47,12 +73,12 @@ class TestFiniteVolume(unittest.TestCase):
         surf_eqn_disc = disc.process_symbol(surf_eqn)
 
         # check constant extrapolates to constant
-        constant_y = np.ones_like(combined_submesh[0].nodes)
+        constant_y = np.ones_like(micro_submesh[0].nodes)
         self.assertEqual(surf_eqn_disc.evaluate(None, constant_y), 1)
 
         # check linear variable extrapolates correctly
-        linear_y = combined_submesh[0].nodes
-        y_surf = combined_submesh[0].nodes[-1] + combined_submesh[0].d_nodes[-1] / 2
+        linear_y = micro_submesh[0].nodes
+        y_surf = micro_submesh[0].nodes[-1] + micro_submesh[0].d_nodes[-1] / 2
         self.assertEqual(surf_eqn_disc.evaluate(None, linear_y), y_surf)
 
     def test_discretise_diffusivity_times_spatial_operator(self):

pip install -e .[dev,docs]
parse_log_pytest
requirements.txt
pytest
apt-get update apt-get install -y gfortran gcc libopenblas-dev liblapack-dev
3.6
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
alabaster==0.7.13
anyio==3.6.2
anytree==2.8.0
argon2-cffi==21.3.0
argon2-cffi-bindings==21.2.0
async-generator==1.10
attrs==22.2.0
autograd==1.6.2
Babel==2.11.0
backcall==0.2.0
bleach==4.1.0
certifi==2021.5.30
cffi==1.15.1
charset-normalizer==2.0.12
comm==0.1.4
contextvars==2.4
cycler==0.11.0
dataclasses==0.8
decorator==5.1.1
defusedxml==0.7.1
docutils==0.17.1
entrypoints==0.4
flake8==5.0.4
future==1.0.0
guzzle-sphinx-theme==0.7.11
idna==3.10
imagesize==1.4.1
immutables==0.19
importlib-metadata==4.2.0
iniconfig==1.1.1
ipykernel==5.5.6
ipython==7.16.3
ipython-genutils==0.2.0
ipywidgets==7.8.5
jedi==0.17.2
Jinja2==3.0.3
json5==0.9.16
jsonschema==3.2.0
jupyter==1.1.1
jupyter-client==7.1.2
jupyter-console==6.4.3
jupyter-core==4.9.2
jupyter-server==1.13.1
jupyterlab==3.2.9
jupyterlab-pygments==0.1.2
jupyterlab-server==2.10.3
jupyterlab_widgets==1.1.11
kiwisolver==1.3.1
MarkupSafe==2.0.1
matplotlib==3.3.4
mccabe==0.7.0
mistune==0.8.4
nbclassic==0.3.5
nbclient==0.5.9
nbconvert==6.0.7
nbformat==5.1.3
nest-asyncio==1.6.0
notebook==6.4.10
numpy==1.19.5
packaging==21.3
pandas==1.1.5
pandocfilters==1.5.1
parso==0.7.1
pexpect==4.9.0
pickleshare==0.7.5
Pillow==8.4.0
pluggy==1.0.0
prometheus-client==0.17.1
prompt-toolkit==3.0.36
ptyprocess==0.7.0
py==1.11.0
-e git+https://github.com/tinosulzer/PyBaMM.git@845cf05818c9369246a6e4c75aa7311f682ad887#egg=pybamm
pycodestyle==2.9.1
pycparser==2.21
pyflakes==2.5.0
Pygments==2.14.0
pyparsing==3.1.4
pyrsistent==0.18.0
pytest==7.0.1
python-dateutil==2.9.0.post0
pytz==2025.2
pyzmq==25.1.2
requests==2.27.1
scipy==1.5.4
Send2Trash==1.8.3
six==1.17.0
sniffio==1.2.0
snowballstemmer==2.2.0
Sphinx==4.3.2
sphinxcontrib-applehelp==1.0.2
sphinxcontrib-devhelp==1.0.2
sphinxcontrib-htmlhelp==2.0.0
sphinxcontrib-jsmath==1.0.1
sphinxcontrib-qthelp==1.0.3
sphinxcontrib-serializinghtml==1.1.5
terminado==0.12.1
testpath==0.6.0
tomli==1.2.3
tornado==6.1
traitlets==4.3.3
typing_extensions==4.1.1
urllib3==1.26.20
wcwidth==0.2.13
webencodings==0.5.1
websocket-client==1.3.1
widgetsnbextension==3.6.10
zipp==3.6.0

name: PyBaMM
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2021.5.30=py36h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.3=he6710b0_2
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - pip=21.2.2=py36h06a4308_0
  - python=3.6.13=h12debd9_1
  - readline=8.2=h5eee18b_0
  - setuptools=58.0.4=py36h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.37.1=pyhd3eb1b0_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - alabaster==0.7.13
      - anyio==3.6.2
      - anytree==2.8.0
      - argon2-cffi==21.3.0
      - argon2-cffi-bindings==21.2.0
      - async-generator==1.10
      - attrs==22.2.0
      - autograd==1.6.2
      - babel==2.11.0
      - backcall==0.2.0
      - bleach==4.1.0
      - cffi==1.15.1
      - charset-normalizer==2.0.12
      - comm==0.1.4
      - contextvars==2.4
      - cycler==0.11.0
      - dataclasses==0.8
      - decorator==5.1.1
      - defusedxml==0.7.1
      - docutils==0.17.1
      - entrypoints==0.4
      - flake8==5.0.4
      - future==1.0.0
      - guzzle-sphinx-theme==0.7.11
      - idna==3.10
      - imagesize==1.4.1
      - immutables==0.19
      - importlib-metadata==4.2.0
      - iniconfig==1.1.1
      - ipykernel==5.5.6
      - ipython==7.16.3
      - ipython-genutils==0.2.0
      - ipywidgets==7.8.5
      - jedi==0.17.2
      - jinja2==3.0.3
      - json5==0.9.16
      - jsonschema==3.2.0
      - jupyter==1.1.1
      - jupyter-client==7.1.2
      - jupyter-console==6.4.3
      - jupyter-core==4.9.2
      - jupyter-server==1.13.1
      - jupyterlab==3.2.9
      - jupyterlab-pygments==0.1.2
      - jupyterlab-server==2.10.3
      - jupyterlab-widgets==1.1.11
      - kiwisolver==1.3.1
      - markupsafe==2.0.1
      - matplotlib==3.3.4
      - mccabe==0.7.0
      - mistune==0.8.4
      - nbclassic==0.3.5
      - nbclient==0.5.9
      - nbconvert==6.0.7
      - nbformat==5.1.3
      - nest-asyncio==1.6.0
      - notebook==6.4.10
      - numpy==1.19.5
      - packaging==21.3
      - pandas==1.1.5
      - pandocfilters==1.5.1
      - parso==0.7.1
      - pexpect==4.9.0
      - pickleshare==0.7.5
      - pillow==8.4.0
      - pluggy==1.0.0
      - prometheus-client==0.17.1
      - prompt-toolkit==3.0.36
      - ptyprocess==0.7.0
      - py==1.11.0
      - pycodestyle==2.9.1
      - pycparser==2.21
      - pyflakes==2.5.0
      - pygments==2.14.0
      - pyparsing==3.1.4
      - pyrsistent==0.18.0
      - pytest==7.0.1
      - python-dateutil==2.9.0.post0
      - pytz==2025.2
      - pyzmq==25.1.2
      - requests==2.27.1
      - scipy==1.5.4
      - send2trash==1.8.3
      - six==1.17.0
      - sniffio==1.2.0
      - snowballstemmer==2.2.0
      - sphinx==4.3.2
      - sphinxcontrib-applehelp==1.0.2
      - sphinxcontrib-devhelp==1.0.2
      - sphinxcontrib-htmlhelp==2.0.0
      - sphinxcontrib-jsmath==1.0.1
      - sphinxcontrib-qthelp==1.0.3
      - sphinxcontrib-serializinghtml==1.1.5
      - terminado==0.12.1
      - testpath==0.6.0
      - tomli==1.2.3
      - tornado==6.1
      - traitlets==4.3.3
      - typing-extensions==4.1.1
      - urllib3==1.26.20
      - wcwidth==0.2.13
      - webencodings==0.5.1
      - websocket-client==1.3.1
      - widgetsnbextension==3.6.10
      - zipp==3.6.0
prefix: /opt/conda/envs/PyBaMM

tests/test_spatial_methods/test_finite_volume.py::TestFiniteVolume::test_extrapolate_left_right
tests/test_models/test_li_ion.py::TestLiIonSPM::test_basic_processing tests/test_models/test_li_ion.py::TestLiIonSPM::test_surface_concentration
tests/test_spatial_methods/test_finite_volume.py::TestFiniteVolume::test_add_ghost_nodes tests/test_spatial_methods/test_finite_volume.py::TestFiniteVolume::test_definite_integral tests/test_spatial_methods/test_finite_volume.py::TestFiniteVolume::test_discretise_diffusivity_times_spatial_operator tests/test_spatial_methods/test_finite_volume.py::TestFiniteVolume::test_discretise_spatial_variable tests/test_spatial_methods/test_finite_volume.py::TestFiniteVolume::test_div_convergence tests/test_spatial_methods/test_finite_volume.py::TestFiniteVolume::test_div_convergence_internal tests/test_spatial_methods/test_finite_volume.py::TestFiniteVolume::test_grad_convergence_with_bcs tests/test_spatial_methods/test_finite_volume.py::TestFiniteVolume::test_grad_convergence_without_bcs tests/test_spatial_methods/test_finite_volume.py::TestFiniteVolume::test_grad_div_shapes_Dirichlet_bcs tests/test_spatial_methods/test_finite_volume.py::TestFiniteVolume::test_grad_div_shapes_Neumann_bcs tests/test_spatial_methods/test_finite_volume.py::TestFiniteVolume::test_grad_div_shapes_mixed_domain tests/test_spatial_methods/test_finite_volume.py::TestFiniteVolume::test_node_to_edge tests/test_spatial_methods/test_finite_volume.py::TestFiniteVolume::test_p2d_add_ghost_nodes tests/test_spatial_methods/test_finite_volume.py::TestFiniteVolume::test_p2d_spherical_grad_div_shapes_Dirichlet_bcs tests/test_spatial_methods/test_finite_volume.py::TestFiniteVolume::test_p2d_spherical_grad_div_shapes_Neumann_bcs tests/test_spatial_methods/test_finite_volume.py::TestFiniteVolume::test_p2d_spherical_operators tests/test_spatial_methods/test_finite_volume.py::TestFiniteVolume::test_spherical_grad_div_shapes_Dirichlet_bcs tests/test_spatial_methods/test_finite_volume.py::TestFiniteVolume::test_spherical_grad_div_shapes_Neumann_bcs tests/test_spatial_methods/test_finite_volume.py::TestFiniteVolume::test_spherical_operators
pybamm/__init__.py pybamm/parameters/parameter_values.py pybamm/expression_tree/unary_operators.py docs/source/expression_tree/unary_operator.rst pybamm/spatial_methods/finite_volume.py pybamm/discretisations/discretisation.py pybamm/solvers/ode_solver.py
pybamm/__init__.py pybamm/parameters/parameter_values.py pybamm/expression_tree/unary_operators.py docs/source/expression_tree/unary_operator.rst pybamm/spatial_methods/finite_volume.py pybamm/discretisations/discretisation.py pybamm/solvers/ode_solver.py