diff --git a/CHANGELOG.md b/CHANGELOG.md
index eb312ad6e..342d6bd17 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,15 +2,16 @@
 
 ## Features
 
-- Add `Interpolant` class to interpolate experimental data (e.g. OCP curves) (#661)
-- Allow parameters to be set by material or by specifying a particular paper (#647)
-- Set relative and absolute tolerances independently in solvers (#645)
-- Add some non-uniform meshes in 1D and 2D (#617)
+- Add method to evaluate parameters more easily (#669 )
+- Add `Interpolant` class to interpolate experimental data (e.g. OCP curves) (#661 )
+- Allow parameters to be set by material or by specifying a particular paper (#647 )
+- Set relative and absolute tolerances independently in solvers (#645 )
+- Add some non-uniform meshes in 1D and 2D (#617 )
 
 ## Optimizations
 
-- Avoid re-checking size when making a copy of an `Index` object (#656)
-- Avoid recalculating `_evaluation_array` when making a copy of a `StateVector` object (#653)
+- Avoid re-checking size when making a copy of an `Index` object (#656 )
+- Avoid recalculating `_evaluation_array` when making a copy of a `StateVector` object (#653 )
 
 ## Bug fixes
 
diff --git a/examples/scripts/compare_comsol/compare_comsol_DFN.py b/examples/scripts/compare_comsol/compare_comsol_DFN.py
index 07081efae..817f34665 100644
--- a/examples/scripts/compare_comsol/compare_comsol_DFN.py
+++ b/examples/scripts/compare_comsol/compare_comsol_DFN.py
@@ -57,7 +57,7 @@ solution = pybamm_model.default_solver.solve(pybamm_model, time)
 # Make Comsol 'model' for comparison
 whole_cell = ["negative electrode", "separator", "positive electrode"]
 comsol_t = comsol_variables["time"]
-L_x = param.process_symbol(pybamm.standard_parameters_lithium_ion.L_x).evaluate()
+L_x = param.evaluate(pybamm.standard_parameters_lithium_ion.L_x)
 
 
 def get_interp_fun(variable, domain):
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 0d3b0a643..793adeff0 100644
--- a/pybamm/models/submodels/current_collector/effective_resistance_current_collector.py
+++ b/pybamm/models/submodels/current_collector/effective_resistance_current_collector.py
@@ -123,15 +123,15 @@ class EffectiveResistance2D(pybamm.BaseModel):
         """
         # Get required processed parameters
         param = self.param
-        l_cn = param_values.process_symbol(param.l_cn).evaluate()
-        l_cp = param_values.process_symbol(param.l_cp).evaluate()
-        l_y = param_values.process_symbol(param.l_y).evaluate()
-        l_z = param_values.process_symbol(param.l_z).evaluate()
-        sigma_cn_prime = param_values.process_symbol(param.sigma_cn_prime).evaluate()
-        sigma_cp_prime = param_values.process_symbol(param.sigma_cp_prime).evaluate()
-        alpha = param_values.process_symbol(param.alpha).evaluate()
-        pot_scale = param_values.process_symbol(param.potential_scale).evaluate()
-        U_ref = param_values.process_symbol(param.U_p_ref - param.U_n_ref).evaluate()
+        l_cn = param_values.evaluate(param.l_cn)
+        l_cp = param_values.evaluate(param.l_cp)
+        l_y = param_values.evaluate(param.l_y)
+        l_z = param_values.evaluate(param.l_z)
+        sigma_cn_prime = param_values.evaluate(param.sigma_cn_prime)
+        sigma_cp_prime = param_values.evaluate(param.sigma_cp_prime)
+        alpha = param_values.evaluate(param.alpha)
+        pot_scale = param_values.evaluate(param.potential_scale)
+        U_ref = param_values.evaluate(param.U_p_ref - param.U_n_ref)
 
         # Process psi and W, and their (average) values at the negative tab
         psi = pybamm.ProcessedVariable(
diff --git a/pybamm/parameters/parameter_values.py b/pybamm/parameters/parameter_values.py
index 05f4b883e..5aff085d3 100644
--- a/pybamm/parameters/parameter_values.py
+++ b/pybamm/parameters/parameter_values.py
@@ -502,3 +502,23 @@ class ParameterValues(dict):
                         x.function.interpolate()
 
         return symbol
+
+    def evaluate(self, symbol):
+        """
+        Process and evaluate a symbol.
+
+        Parameters
+        ----------
+        symbol : :class:`pybamm.Symbol`
+            Symbol or Expression tree to evaluate
+
+        Returns
+        -------
+        number of array
+            The evaluated symbol
+        """
+        processed_symbol = self.process_symbol(symbol)
+        if processed_symbol.is_constant() and processed_symbol.evaluates_to_number():
+            return processed_symbol.evaluate()
+        else:
+            raise ValueError("symbol must evaluate to a constant scalar")
diff --git a/results/2plus1D/compare_lithium_ion_2plus1D.py b/results/2plus1D/compare_lithium_ion_2plus1D.py
index fb7c51b31..cce573d2d 100644
--- a/results/2plus1D/compare_lithium_ion_2plus1D.py
+++ b/results/2plus1D/compare_lithium_ion_2plus1D.py
@@ -79,8 +79,8 @@ plt.xlabel("Time [h]")
 plt.ylabel("Terminal voltage [V]")
 plt.legend()
 # add C-rate, delta, and alpha to title
-delta = param.process_symbol(pybamm.standard_parameters_lithium_ion.delta).evaluate()
-alpha = param.process_symbol(pybamm.standard_parameters_lithium_ion.alpha).evaluate()
+delta = param.evaluate(pybamm.standard_parameters_lithium_ion.delta)
+alpha = param.evaluate(pybamm.standard_parameters_lithium_ion.alpha)
 plt.title(
     r"C-rate = {:3d}, $\alpha$ = {:.6f} , $\delta$ = {:.6f}".format(
         C_rate, alpha, delta
diff --git a/results/2plus1D/compare_spmecc.py b/results/2plus1D/compare_spmecc.py
index 68dec7154..2f4cd2f13 100644
--- a/results/2plus1D/compare_spmecc.py
+++ b/results/2plus1D/compare_spmecc.py
@@ -63,9 +63,7 @@ for name in ["Average SPMe", "2+1D SPMe"]:
     # add current collector Ohmic losses to average SPMEe to get SPMeCC voltage
     if model.name == "Average SPMe":
         current = pybamm.ProcessedVariable(model.variables["Current [A]"], t, y)(t)
-        delta = param.process_symbol(
-            pybamm.standard_parameters_lithium_ion.delta
-        ).evaluate()
+        delta = param.evaluate(pybamm.standard_parameters_lithium_ion.delta)
         R_cc = param.process_symbol(
             cc_model.variables["Effective current collector resistance [Ohm]"]
         ).evaluate(
diff --git a/results/2plus1D/spm_2plus1D_tab_grid.py b/results/2plus1D/spm_2plus1D_tab_grid.py
index b4211bb40..88fa3e5dd 100644
--- a/results/2plus1D/spm_2plus1D_tab_grid.py
+++ b/results/2plus1D/spm_2plus1D_tab_grid.py
@@ -22,7 +22,7 @@ param = model.default_parameter_values
 # adjust current to correspond to a typical current density of 24 [A.m-2]
 C_rate = 1
 param["Typical current [A]"] = (
-    C_rate * 24 * param.process_symbol(pybamm.geometric_parameters.A_cc).evaluate()
+    C_rate * 24 * param.evaluate(pybamm.geometric_parameters.A_cc)
 )
 param.process_model(model)
 param.process_geometry(geometry)
@@ -39,9 +39,7 @@ var_pts = {
     var.z: 5,
 }
 submesh_types = model.default_submesh_types
-submesh_types[
-    "current collector"
-] = pybamm.ScikitExponential2DSubMesh
+submesh_types["current collector"] = pybamm.ScikitExponential2DSubMesh
 # depnding on number of points in y-z plane may need to increase recursion depth...
 sys.setrecursionlimit(10000)
 mesh = pybamm.Mesh(geometry, submesh_types, var_pts)
diff --git a/results/2plus1D/spmecc.py b/results/2plus1D/spmecc.py
index 26776b15c..89360c571 100644
--- a/results/2plus1D/spmecc.py
+++ b/results/2plus1D/spmecc.py
@@ -41,7 +41,7 @@ t, y = solution.t, solution.y
 time = pybamm.ProcessedVariable(cell_model.variables["Time [h]"], t, y)(t)
 voltage = pybamm.ProcessedVariable(cell_model.variables["Terminal voltage [V]"], t, y)
 current = pybamm.ProcessedVariable(cell_model.variables["Current [A]"], t, y)(t)
-delta = param.process_symbol(pybamm.standard_parameters_lithium_ion.delta).evaluate()
+delta = param.evaluate(pybamm.standard_parameters_lithium_ion.delta)
 R_cc = param.process_symbol(
     cc_model.variables["Effective current collector resistance [Ohm]"]
 ).evaluate(t=cc_solution.t, y=cc_solution.y)[0][0]
diff --git a/results/2plus1D/user_mesh_spm_1plus1D.py b/results/2plus1D/user_mesh_spm_1plus1D.py
index 811ee2f98..a63950026 100644
--- a/results/2plus1D/user_mesh_spm_1plus1D.py
+++ b/results/2plus1D/user_mesh_spm_1plus1D.py
@@ -19,7 +19,7 @@ geometry = model.default_geometry
 # load parameter values and process model and geometry
 param = model.default_parameter_values
 C_rate = 1
-current_1C = 24 * param.process_symbol(pybamm.geometric_parameters.A_cc).evaluate()
+current_1C = 24 * param.evaluate(pybamm.geometric_parameters.A_cc)
 param.update(
     {
         "Typical current [A]": C_rate * current_1C,

Add method to evaluate parameters
Add method `ParameterValues.evaluate` which processes a symbol and then evaluates it. Just saves a tiny bit of ugly syntax.
diff --git a/tests/integration/test_models/standard_output_tests.py b/tests/integration/test_models/standard_output_tests.py
index 5c100105f..b019737fc 100644
--- a/tests/integration/test_models/standard_output_tests.py
+++ b/tests/integration/test_models/standard_output_tests.py
@@ -90,8 +90,8 @@ class BaseOutputTest(object):
             self.r_p_edge = disc.mesh["positive particle"][0].edges
 
         # Useful parameters
-        self.l_n = param.process_symbol(pybamm.geometric_parameters.l_n).evaluate()
-        self.l_p = param.process_symbol(pybamm.geometric_parameters.l_p).evaluate()
+        self.l_n = param.evaluate(pybamm.geometric_parameters.l_n)
+        self.l_p = param.evaluate(pybamm.geometric_parameters.l_p)
 
         if isinstance(self.model, pybamm.lithium_ion.BaseModel):
             current_param = pybamm.standard_parameters_lithium_ion.current_with_time
@@ -635,9 +635,9 @@ class VelocityTests(BaseOutputTest):
         t, x_n, x_p = self.t, self.x_n, self.x_p
 
         beta_n = pybamm.standard_parameters_lead_acid.beta_n
-        beta_n = self.param.process_symbol(beta_n).evaluate()
+        beta_n = self.param.evaluate(beta_n)
         beta_p = pybamm.standard_parameters_lead_acid.beta_p
-        beta_p = self.param.process_symbol(beta_p).evaluate()
+        beta_p = self.param.evaluate(beta_p)
 
         np.testing.assert_array_almost_equal(
             self.v_box(t, x_n), beta_n * self.i_e(t, x_n)
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 555da6a43..73ad08911 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
@@ -21,122 +21,82 @@ class TestDimensionlessParameterValues(unittest.TestCase):
         "particle geometry"
         # a_n dimensional
         np.testing.assert_almost_equal(
-            values.process_symbol(param.a_n_dim).evaluate(None, None),
-            0.18 * 10 ** (6),
-            2,
+            values.evaluate(param.a_n_dim), 0.18 * 10 ** (6), 2
         )
         # R_n dimensional
-        np.testing.assert_almost_equal(
-            values.process_symbol(param.R_n).evaluate(None, None), 1 * 10 ** (-5), 2
-        )
+        np.testing.assert_almost_equal(values.evaluate(param.R_n), 1 * 10 ** (-5), 2)
 
         # a_n
-        np.testing.assert_almost_equal(
-            values.process_symbol(param.a_n).evaluate(None, None), 1.8, 2
-        )
+        np.testing.assert_almost_equal(values.evaluate(param.a_n), 1.8, 2)
 
         # a_p dimensional
         np.testing.assert_almost_equal(
-            values.process_symbol(param.a_p_dim).evaluate(None, None),
-            0.15 * 10 ** (6),
-            2,
+            values.evaluate(param.a_p_dim), 0.15 * 10 ** (6), 2
         )
 
         # R_p dimensional
-        np.testing.assert_almost_equal(
-            values.process_symbol(param.R_n).evaluate(None, None), 1 * 10 ** (-5), 2
-        )
+        np.testing.assert_almost_equal(values.evaluate(param.R_n), 1 * 10 ** (-5), 2)
 
         # a_p
-        np.testing.assert_almost_equal(
-            values.process_symbol(param.a_p).evaluate(None, None), 1.5, 2
-        )
+        np.testing.assert_almost_equal(values.evaluate(param.a_p), 1.5, 2)
 
         "reaction rates"
         # m_n*
         np.testing.assert_almost_equal(
-            values.process_symbol(param.m_n_dimensional(param.T_ref)).evaluate(
-                None, None
-            ),
-            2 * 10 ** (-5),
-            8,
+            values.evaluate(param.m_n_dimensional(param.T_ref)), 2 * 10 ** (-5), 8
         )
 
         np.testing.assert_almost_equal(
-            values.process_symbol(1 / param.C_r_n * c_rate).evaluate(None, None),
-            26.6639,
-            3,
+            values.evaluate(1 / param.C_r_n * c_rate), 26.6639, 3
         )
 
         # m_p*
         np.testing.assert_almost_equal(
-            values.process_symbol(param.m_p_dimensional(param.T_ref)).evaluate(
-                None, None
-            ),
-            6 * 10 ** (-7),
-            8,
+            values.evaluate(param.m_p_dimensional(param.T_ref)), 6 * 10 ** (-7), 8
         )
 
         # gamma_p / C_r_p
         np.testing.assert_almost_equal(
-            values.process_symbol(param.gamma_p / param.C_r_p * c_rate).evaluate(
-                None, None
-            ),
-            1.366,
-            3,
+            values.evaluate(param.gamma_p / param.C_r_p * c_rate), 1.366, 3
         )
 
         "particle dynamics"
         # neg diffusion coefficient
         np.testing.assert_almost_equal(
-            values.process_symbol(
-                param.D_n_dimensional(param.c_n_init, param.T_ref)
-            ).evaluate(None, None),
+            values.evaluate(param.D_n_dimensional(param.c_n_init, param.T_ref)),
             3.9 * 10 ** (-14),
             2,
         )
 
         # neg diffusion timescale
         np.testing.assert_almost_equal(
-            values.process_symbol(param.tau_diffusion_n).evaluate(None, None),
-            2.5641 * 10 ** (3),
-            2,
+            values.evaluate(param.tau_diffusion_n), 2.5641 * 10 ** (3), 2
         )
 
         # tau_n / tau_d (1/gamma_n in Scott's transfer)
-        np.testing.assert_almost_equal(
-            values.process_symbol(param.C_n / c_rate).evaluate(None, None), 0.11346, 3
-        )
+        np.testing.assert_almost_equal(values.evaluate(param.C_n / c_rate), 0.11346, 3)
 
         # pos diffusion coefficient
         np.testing.assert_almost_equal(
-            values.process_symbol(
-                param.D_p_dimensional(param.c_p_init, param.T_ref)
-            ).evaluate(None, None),
+            values.evaluate(param.D_p_dimensional(param.c_p_init, param.T_ref)),
             1 * 10 ** (-13),
             2,
         )
 
         # pos diffusion timescale
         np.testing.assert_almost_equal(
-            values.process_symbol(param.tau_diffusion_p).evaluate(None, None),
-            1 * 10 ** (3),
-            2,
+            values.evaluate(param.tau_diffusion_p), 1 * 10 ** (3), 2
         )
 
         # tau_p / tau_d (1/gamma_p in Scott's transfer)
-        np.testing.assert_almost_equal(
-            values.process_symbol(param.C_p / c_rate).evaluate(None, None), 0.044249, 3
-        )
+        np.testing.assert_almost_equal(values.evaluate(param.C_p / c_rate), 0.044249, 3)
 
         "electrolyte dynamics"
         # typical diffusion coefficient (we should change the typ value in paper to
         # match this one. We take this parameter excluding the exp(-0.65) in the
         # paper at the moment
         np.testing.assert_almost_equal(
-            values.process_symbol(
-                param.D_e_dimensional(param.c_e_typ, param.T_ref)
-            ).evaluate(None, None),
+            values.evaluate(param.D_e_dimensional(param.c_e_typ, param.T_ref)),
             5.34 * 10 ** (-10) * np.exp(-0.65),
             10,
         )
@@ -144,21 +104,15 @@ class TestDimensionlessParameterValues(unittest.TestCase):
         # electrolyte diffusion timescale (accounting for np.exp(-0.65) in
         # diffusion_typ). Change value in paper to this.
         np.testing.assert_almost_equal(
-            values.process_symbol(param.tau_diffusion_e).evaluate(None, None),
-            181.599,
-            3,
+            values.evaluate(param.tau_diffusion_e), 181.599, 3
         )
 
         # C_e
-        np.testing.assert_almost_equal(
-            values.process_symbol(param.C_e / c_rate).evaluate(None, None), 0.008, 3
-        )
+        np.testing.assert_almost_equal(values.evaluate(param.C_e / c_rate), 0.008, 3)
 
         # electrolyte conductivity
         np.testing.assert_almost_equal(
-            values.process_symbol(
-                param.kappa_e_dimensional(param.c_e_typ, param.T_ref)
-            ).evaluate(None, None),
+            values.evaluate(param.kappa_e_dimensional(param.c_e_typ, param.T_ref)),
             1.1045,
             3,
         )
@@ -167,32 +121,26 @@ class TestDimensionlessParameterValues(unittest.TestCase):
         # F R / T (should be equal to old 1 / Lambda)
         old_Lambda = 38
         np.testing.assert_almost_equal(
-            values.process_symbol(param.potential_scale).evaluate(None, None),
-            1 / old_Lambda,
-            3,
+            values.evaluate(param.potential_scale), 1 / old_Lambda, 3
         )
 
         "electrode conductivities"
         # neg dimensional
-        np.testing.assert_almost_equal(
-            values.process_symbol(param.sigma_n_dim).evaluate(None, None), 100, 3
-        )
+        np.testing.assert_almost_equal(values.evaluate(param.sigma_n_dim), 100, 3)
 
         # neg dimensionless (old sigma_n / old_Lambda ) (this is different to values
         # in paper so check again, it is close enough though for now)
         np.testing.assert_almost_equal(
-            values.process_symbol(param.sigma_n * c_rate).evaluate(None, None), 475.7, 1
+            values.evaluate(param.sigma_n * c_rate), 475.7, 1
         )
 
         # neg dimensional
-        np.testing.assert_almost_equal(
-            values.process_symbol(param.sigma_p_dim).evaluate(None, None), 10, 3
-        )
+        np.testing.assert_almost_equal(values.evaluate(param.sigma_p_dim), 10, 3)
 
         # neg dimensionless (old sigma_n / old_Lambda ) (this is different to values in
         # paper so check again, it is close enough for now though)
         np.testing.assert_almost_equal(
-            values.process_symbol(param.sigma_p * c_rate).evaluate(None, None), 47.57, 1
+            values.evaluate(param.sigma_p * c_rate), 47.57, 1
         )
 
     def test_thermal_parameters(self):
@@ -201,72 +149,48 @@ class TestDimensionlessParameterValues(unittest.TestCase):
         c_rate = param.i_typ / 24
 
         # Density
-        np.testing.assert_almost_equal(
-            values.process_symbol(param.rho_cn).evaluate(), 1.9019, 2
-        )
-        np.testing.assert_almost_equal(
-            values.process_symbol(param.rho_n).evaluate(), 0.6403, 2
-        )
-        np.testing.assert_almost_equal(
-            values.process_symbol(param.rho_s).evaluate(), 0.1535, 2
-        )
-        np.testing.assert_almost_equal(
-            values.process_symbol(param.rho_p).evaluate(), 1.2605, 2
-        )
-        np.testing.assert_almost_equal(
-            values.process_symbol(param.rho_cp).evaluate(), 1.3403, 2
-        )
+        np.testing.assert_almost_equal(values.evaluate(param.rho_cn), 1.9019, 2)
+        np.testing.assert_almost_equal(values.evaluate(param.rho_n), 0.6403, 2)
+        np.testing.assert_almost_equal(values.evaluate(param.rho_s), 0.1535, 2)
+        np.testing.assert_almost_equal(values.evaluate(param.rho_p), 1.2605, 2)
+        np.testing.assert_almost_equal(values.evaluate(param.rho_cp), 1.3403, 2)
 
         # Thermal conductivity
-        np.testing.assert_almost_equal(
-            values.process_symbol(param.lambda_cn).evaluate(), 6.7513, 2
-        )
-        np.testing.assert_almost_equal(
-            values.process_symbol(param.lambda_n).evaluate(), 0.0296, 2
-        )
-        np.testing.assert_almost_equal(
-            values.process_symbol(param.lambda_s).evaluate(), 0.0027, 2
-        )
-        np.testing.assert_almost_equal(
-            values.process_symbol(param.lambda_p).evaluate(), 0.0354, 2
-        )
-        np.testing.assert_almost_equal(
-            values.process_symbol(param.lambda_cp).evaluate(), 3.9901, 2
-        )
+        np.testing.assert_almost_equal(values.evaluate(param.lambda_cn), 6.7513, 2)
+        np.testing.assert_almost_equal(values.evaluate(param.lambda_n), 0.0296, 2)
+        np.testing.assert_almost_equal(values.evaluate(param.lambda_s), 0.0027, 2)
+        np.testing.assert_almost_equal(values.evaluate(param.lambda_p), 0.0354, 2)
+        np.testing.assert_almost_equal(values.evaluate(param.lambda_cp), 3.9901, 2)
 
         # other thermal parameters
 
         # note: in paper this is 0.0534 * c_rate which conflicts with this
         # if we do C_th * c_rate we get 0.0534 so probably error in paper
         # np.testing.assert_almost_equal(
-        #     values.process_symbol(param.C_th / c_rate).evaluate(), 0.0253, 2
+        #     values.evaluate(param.C_th / c_rate), 0.0253, 2
         # )
 
-        np.testing.assert_almost_equal(
-            values.process_symbol(param.Theta / c_rate).evaluate(), 0.008, 2
-        )
+        np.testing.assert_almost_equal(values.evaluate(param.Theta / c_rate), 0.008, 2)
 
-        np.testing.assert_almost_equal(
-            values.process_symbol(param.h).evaluate(), 3.7881 * 10 ** (-5), 7
-        )
+        np.testing.assert_almost_equal(values.evaluate(param.h), 3.7881 * 10 ** (-5), 7)
 
         # np.testing.assert_almost_equal(
-        #     values.process_symbol(param.B / c_rate).evaluate(), 36.216, 2
+        #     values.evaluate(param.B / c_rate), 36.216, 2
         # )
 
-        np.testing.assert_equal(values.process_symbol(param.T_init).evaluate(), 0)
+        np.testing.assert_equal(values.evaluate(param.T_init), 0)
 
         # test timescale
         # np.testing.assert_almost_equal(
-        #     values.process_symbol(param.tau_th_yz).evaluate(), 1.4762 * 10 ** (3), 2
+        #     values.evaluate(param.tau_th_yz), 1.4762 * 10 ** (3), 2
         # )
 
         # thermal = pybamm.thermal_parameters
         # np.testing.assert_almost_equal(
-        # values.process_symbol(thermal.rho_eff_dim).evaluate(), 1.8116 * 10 ** (6), 2
+        # values.evaluate(thermal.rho_eff_dim), 1.8116 * 10 ** (6), 2
         # )
         # np.testing.assert_almost_equal(
-        #     values.process_symbol(thermal.lambda_eff_dim).evaluate(), 59.3964, 2
+        #     values.evaluate(thermal.lambda_eff_dim), 59.3964, 2
         # )
 
     def test_parameter_functions(self):
@@ -276,17 +200,17 @@ class TestDimensionlessParameterValues(unittest.TestCase):
         c_test = pybamm.Scalar(0.5)
         T_test = pybamm.Scalar(0)
 
-        values.process_symbol(param.U_n(c_test, T_test)).evaluate()
-        values.process_symbol(param.U_p(c_test, T_test)).evaluate()
-        values.process_symbol(param.dUdT_n(c_test)).evaluate()
-        values.process_symbol(param.dUdT_p(c_test)).evaluate()
+        values.evaluate(param.U_n(c_test, T_test))
+        values.evaluate(param.U_p(c_test, T_test))
+        values.evaluate(param.dUdT_n(c_test))
+        values.evaluate(param.dUdT_p(c_test))
 
-        values.process_symbol(param.D_p(c_test, T_test)).evaluate()
-        values.process_symbol(param.D_n(c_test, T_test)).evaluate()
+        values.evaluate(param.D_p(c_test, T_test))
+        values.evaluate(param.D_n(c_test, T_test))
 
         c_e_test = pybamm.Scalar(1)
-        values.process_symbol(param.D_e(c_e_test, T_test)).evaluate()
-        values.process_symbol(param.kappa_e(c_e_test, T_test)).evaluate()
+        values.evaluate(param.D_e(c_e_test, T_test))
+        values.evaluate(param.kappa_e(c_e_test, T_test))
 
 
 if __name__ == "__main__":
diff --git a/tests/unit/test_parameters/test_parameter_values.py b/tests/unit/test_parameters/test_parameter_values.py
index db92388f9..fca7caf83 100644
--- a/tests/unit/test_parameters/test_parameter_values.py
+++ b/tests/unit/test_parameters/test_parameter_values.py
@@ -451,6 +451,21 @@ class TestParameterValues(unittest.TestCase):
         ):
             parameter_values.process_model(model)
 
+    def test_evaluate(self):
+        parameter_values = pybamm.ParameterValues({"a": 1, "b": 2, "c": 3})
+        a = pybamm.Parameter("a")
+        b = pybamm.Parameter("b")
+        c = pybamm.Parameter("c")
+        self.assertEqual(parameter_values.evaluate(a), 1)
+        self.assertEqual(parameter_values.evaluate(a + (b * c)), 7)
+
+        y = pybamm.StateVector(slice(0, 1))
+        with self.assertRaises(ValueError):
+            parameter_values.evaluate(y)
+        array = pybamm.Array(np.array([1, 2, 3]))
+        with self.assertRaises(ValueError):
+            parameter_values.evaluate(array)
+
 
 if __name__ == "__main__":
     print("Add -v for more debug output")

pip install -e .[dev,docs]
parse_log_pytest
requirements.txt
pytest
apt-get update apt-get install -y gcc gfortran libopenblas-dev liblapack-dev
3.7
requirements/base.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
alabaster==0.7.13
anyio==3.7.1
anytree==2.12.1
argon2-cffi==23.1.0
argon2-cffi-bindings==21.2.0
attrs==24.2.0
autograd==1.6.2
Babel==2.14.0
backcall==0.2.0
beautifulsoup4==4.13.3
black==23.3.0
bleach==6.0.0
certifi @ file:///croot/certifi_1671487769961/work/certifi
cffi==1.15.1
charset-normalizer==3.4.1
click==8.1.8
comm==0.1.4
cycler==0.11.0
debugpy==1.7.0
decorator==5.1.1
defusedxml==0.7.1
docutils==0.17.1
entrypoints==0.4
exceptiongroup==1.2.2
fastjsonschema==2.21.1
flake8==5.0.4
fonttools==4.38.0
future==1.0.0
guzzle-sphinx-theme==0.7.11
idna==3.10
imagesize==1.4.1
importlib-metadata==4.2.0
importlib-resources==5.12.0
iniconfig==2.0.0
ipykernel==6.16.2
ipython==7.34.0
ipython-genutils==0.2.0
ipywidgets==8.1.5
jedi==0.19.2
Jinja2==3.1.6
json5==0.9.16
jsonschema==4.17.3
jupyter==1.1.1
jupyter-console==6.6.3
jupyter-server==1.24.0
jupyter_client==7.4.9
jupyter_core==4.12.0
jupyterlab==3.5.3
jupyterlab-pygments==0.2.2
jupyterlab_server==2.15.2
jupyterlab_widgets==3.0.13
kiwisolver==1.4.5
MarkupSafe==2.1.5
matplotlib==3.5.3
matplotlib-inline==0.1.6
mccabe==0.7.0
mistune==3.0.2
mypy-extensions==1.0.0
nbclassic==1.2.0
nbclient==0.7.4
nbconvert==7.6.0
nbformat==5.8.0
nest-asyncio==1.6.0
notebook==6.5.7
notebook_shim==0.2.4
numpy==1.21.6
packaging==24.0
pandas==1.3.5
pandocfilters==1.5.1
parso==0.8.4
pathspec==0.11.2
pexpect==4.9.0
pickleshare==0.7.5
Pillow==9.5.0
pkgutil_resolve_name==1.3.10
platformdirs==4.0.0
pluggy==1.2.0
prometheus-client==0.17.1
prompt_toolkit==3.0.48
psutil==7.0.0
ptyprocess==0.7.0
-e git+https://github.com/pybamm-team/PyBaMM.git@1028e78493669935c0d100d74a08eaad1a41a239#egg=pybamm
pycodestyle==2.9.1
pycparser==2.21
pyflakes==2.5.0
Pygments==2.17.2
pyparsing==3.1.4
pyrsistent==0.19.3
pytest==7.4.4
python-dateutil==2.9.0.post0
pytz==2025.2
pyzmq==26.2.1
requests==2.31.0
scikit-fem==8.1.0
scipy==1.7.3
Send2Trash==1.8.3
six==1.17.0
sniffio==1.3.1
snowballstemmer==2.2.0
soupsieve==2.4.1
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.17.1
tinycss2==1.2.1
tomli==2.0.1
tornado==6.2
traitlets==5.9.0
typed-ast==1.5.5
typing_extensions==4.7.1
urllib3==2.0.7
wcwidth==0.2.13
webencodings==0.5.1
websocket-client==1.6.1
widgetsnbextension==4.0.13
zipp==3.15.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=2022.12.7=py37h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - 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=22.3.1=py37h06a4308_0
  - python=3.7.16=h7a1cb2a_0
  - readline=8.2=h5eee18b_0
  - setuptools=65.6.3=py37h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.38.4=py37h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - alabaster==0.7.13
      - anyio==3.7.1
      - anytree==2.12.1
      - argon2-cffi==23.1.0
      - argon2-cffi-bindings==21.2.0
      - attrs==24.2.0
      - autograd==1.6.2
      - babel==2.14.0
      - backcall==0.2.0
      - beautifulsoup4==4.13.3
      - black==23.3.0
      - bleach==6.0.0
      - cffi==1.15.1
      - charset-normalizer==3.4.1
      - click==8.1.8
      - comm==0.1.4
      - cycler==0.11.0
      - debugpy==1.7.0
      - decorator==5.1.1
      - defusedxml==0.7.1
      - docutils==0.17.1
      - entrypoints==0.4
      - exceptiongroup==1.2.2
      - fastjsonschema==2.21.1
      - flake8==5.0.4
      - fonttools==4.38.0
      - future==1.0.0
      - guzzle-sphinx-theme==0.7.11
      - idna==3.10
      - imagesize==1.4.1
      - importlib-metadata==4.2.0
      - importlib-resources==5.12.0
      - iniconfig==2.0.0
      - ipykernel==6.16.2
      - ipython==7.34.0
      - ipython-genutils==0.2.0
      - ipywidgets==8.1.5
      - jedi==0.19.2
      - jinja2==3.1.6
      - json5==0.9.16
      - jsonschema==4.17.3
      - jupyter==1.1.1
      - jupyter-client==7.4.9
      - jupyter-console==6.6.3
      - jupyter-core==4.12.0
      - jupyter-server==1.24.0
      - jupyterlab==3.5.3
      - jupyterlab-pygments==0.2.2
      - jupyterlab-server==2.15.2
      - jupyterlab-widgets==3.0.13
      - kiwisolver==1.4.5
      - markupsafe==2.1.5
      - matplotlib==3.5.3
      - matplotlib-inline==0.1.6
      - mccabe==0.7.0
      - mistune==3.0.2
      - mypy-extensions==1.0.0
      - nbclassic==1.2.0
      - nbclient==0.7.4
      - nbconvert==7.6.0
      - nbformat==5.8.0
      - nest-asyncio==1.6.0
      - notebook==6.5.7
      - notebook-shim==0.2.4
      - numpy==1.21.6
      - packaging==24.0
      - pandas==1.3.5
      - pandocfilters==1.5.1
      - parso==0.8.4
      - pathspec==0.11.2
      - pexpect==4.9.0
      - pickleshare==0.7.5
      - pillow==9.5.0
      - pkgutil-resolve-name==1.3.10
      - platformdirs==4.0.0
      - pluggy==1.2.0
      - prometheus-client==0.17.1
      - prompt-toolkit==3.0.48
      - psutil==7.0.0
      - ptyprocess==0.7.0
      - pycodestyle==2.9.1
      - pycparser==2.21
      - pyflakes==2.5.0
      - pygments==2.17.2
      - pyparsing==3.1.4
      - pyrsistent==0.19.3
      - pytest==7.4.4
      - python-dateutil==2.9.0.post0
      - pytz==2025.2
      - pyzmq==26.2.1
      - requests==2.31.0
      - scikit-fem==8.1.0
      - scipy==1.7.3
      - send2trash==1.8.3
      - six==1.17.0
      - sniffio==1.3.1
      - snowballstemmer==2.2.0
      - soupsieve==2.4.1
      - 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.17.1
      - tinycss2==1.2.1
      - tomli==2.0.1
      - tornado==6.2
      - traitlets==5.9.0
      - typed-ast==1.5.5
      - typing-extensions==4.7.1
      - urllib3==2.0.7
      - wcwidth==0.2.13
      - webencodings==0.5.1
      - websocket-client==1.6.1
      - widgetsnbextension==4.0.13
      - zipp==3.15.0
prefix: /opt/conda/envs/PyBaMM

tests/unit/test_parameters/test_dimensionless_parameter_values_lithium_ion.py::TestDimensionlessParameterValues::test_lithium_ion tests/unit/test_parameters/test_dimensionless_parameter_values_lithium_ion.py::TestDimensionlessParameterValues::test_parameter_functions tests/unit/test_parameters/test_dimensionless_parameter_values_lithium_ion.py::TestDimensionlessParameterValues::test_thermal_parameters tests/unit/test_parameters/test_parameter_values.py::TestParameterValues::test_evaluate
tests/unit/test_parameters/test_parameter_values.py::TestParameterValues::test_check_and_update_parameter_values tests/unit/test_parameters/test_parameter_values.py::TestParameterValues::test_init tests/unit/test_parameters/test_parameter_values.py::TestParameterValues::test_interpolant_against_function tests/unit/test_parameters/test_parameter_values.py::TestParameterValues::test_multi_var_function_parameter tests/unit/test_parameters/test_parameter_values.py::TestParameterValues::test_multi_var_function_with_parameters tests/unit/test_parameters/test_parameter_values.py::TestParameterValues::test_process_complex_expression tests/unit/test_parameters/test_parameter_values.py::TestParameterValues::test_process_empty_model tests/unit/test_parameters/test_parameter_values.py::TestParameterValues::test_process_function_parameter tests/unit/test_parameters/test_parameter_values.py::TestParameterValues::test_process_inline_function_parameters tests/unit/test_parameters/test_parameter_values.py::TestParameterValues::test_process_interpolant tests/unit/test_parameters/test_parameter_values.py::TestParameterValues::test_process_model tests/unit/test_parameters/test_parameter_values.py::TestParameterValues::test_process_symbol tests/unit/test_parameters/test_parameter_values.py::TestParameterValues::test_read_parameters_csv tests/unit/test_parameters/test_parameter_values.py::TestParameterValues::test_update tests/unit/test_parameters/test_parameter_values.py::TestParameterValues::test_update_from_chemistry
pybamm/parameters/parameter_values.py results/2plus1D/spm_2plus1D_tab_grid.py CHANGELOG.md results/2plus1D/compare_lithium_ion_2plus1D.py results/2plus1D/spmecc.py examples/scripts/compare_comsol/compare_comsol_DFN.py pybamm/models/submodels/current_collector/effective_resistance_current_collector.py results/2plus1D/compare_spmecc.py results/2plus1D/user_mesh_spm_1plus1D.py
pybamm/parameters/parameter_values.py results/2plus1D/spm_2plus1D_tab_grid.py CHANGELOG.md results/2plus1D/compare_lithium_ion_2plus1D.py results/2plus1D/spmecc.py examples/scripts/compare_comsol/compare_comsol_DFN.py pybamm/models/submodels/current_collector/effective_resistance_current_collector.py results/2plus1D/compare_spmecc.py results/2plus1D/user_mesh_spm_1plus1D.py