diff --git a/CHANGELOG.md b/CHANGELOG.md
index 100e85f..6552bcc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,9 +10,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 ### Added
 
 - The `ForceField` object has a new method `compute` that can selectively compute
-  the energy, the forces and/or the force-contribution to the pressure.
-  This improves the efficiency in applications where not all quantities are of interest,
-  such as in Monte Carlo simulations.
+  the energy only or the energy, forces and the force-contribution to the pressure.
+  This improves the efficiency in applications where derivatives are of interest,
+  e.g. in Monte Carlo simulations.
 - The `ForceField` object is extended with `try_move` and `accept_move`
   to support (relatively) efficient Monte Carlo algorithms with TinyFF.
 - Basic analysis routines for radial distribution functions and autocorrelation functions.
@@ -24,12 +24,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 - The `ForceField` class requires the `NBuild` instance to be provided as a keyword argument.
   For example: `ForceField([LennardJones()], nbuild=NBuildSimple)`.
 - The `ForceField.__call__` method is replaced by `ForceField.compute`,
-  which has a different API with new `do_*` arguments.
+  which has a different API with a new `nderiv=0` arguments.
   By default, only the energy is computed.
-  You must request forces and pressure explicitly.
-  The function always returns a list of results, even if there is only one.
+  You must request forces and pressure explicitly by setting `nderiv=1`.
+  The function always returns a list of results, even if `nderiv=0`.
 - The `PairwiseTerm.compute` (previously `PairwisePotential.compute`) has a new API:
-  it takes `do_*` arguments to decide what is computed (energy and or derivative).
+  it takes an `nderiv` arguments to decide what is computed
+  (energy or energy and derivative).
   It returns a list of requested results.
   By default, only the energy is computed.
 - The `ForceTerm.__call__` method has been replaced by `PairwiseTerm.compute_nlist`.
diff --git a/README.md b/README.md
index 2a4bdb0..be5c1d1 100644
--- a/README.md
+++ b/README.md
@@ -79,12 +79,11 @@ atpos = np.array([[0.0, 0.0, 1.0], [1.0, 2.0, 0.0]])
 cell_length = 20.0
 
 # Compute a selection of results with ff.compute.
-#   The ff.compute method has `do_*` arguments to compute only some results:
-#   - `do_energy` (default True)
-#   - `do_forces` (default False)
-#   - `do_press` (default False).
+#   The ff.compute method has an `nderiv` arguments to compute only some results:
+#   - `nderiv=0` (default): compute only the energy
+#   - `nderiv=1`: compute the energy, forces and force contribution to the pressure.
 #   Requested results are put in a list, even in only one result is requested.
-potential_energy, forces = ff.compute(atpos, cell_length, do_forces=True)
+potential_energy, forces, press = ff.compute(atpos, cell_length, nderiv=1)
 ```
 
 This basic recipe can be extended by passing additional options
diff --git a/src/tinyff/atomsmithy.py b/src/tinyff/atomsmithy.py
index 29b52ac..911e659 100644
--- a/src/tinyff/atomsmithy.py
+++ b/src/tinyff/atomsmithy.py
@@ -102,7 +102,7 @@ def build_random_cell(
 
     def costgrad(atpos_raveled):
         atpos = atpos_raveled.reshape(-1, 3)
-        energy, force = ff.compute(atpos, cell_length, do_forces=True)
+        energy, force, _ = ff.compute(atpos, cell_length, nderiv=1)
         return energy, -force.ravel()
 
     # Optimize and return structure
diff --git a/src/tinyff/forcefield.py b/src/tinyff/forcefield.py
index aad7e06..d1ec950 100644
--- a/src/tinyff/forcefield.py
+++ b/src/tinyff/forcefield.py
@@ -47,15 +47,7 @@ class ForceField:
     nbuild: NBuild = attrs.field(validator=attrs.validators.instance_of(NBuild), kw_only=True)
     """Algorithm to build the neigborlist."""
 
-    def compute(
-        self,
-        atpos: NDArray,
-        cell_lengths: ArrayLike | float,
-        *,
-        do_energy: bool = True,
-        do_forces: bool = False,
-        do_press: bool = False,
-    ):
+    def compute(self, atpos: NDArray, cell_lengths: ArrayLike | float, nderiv: int = 0):
         """Compute microscopic properties related to the potential energy.
 
         Parameters
@@ -66,12 +58,9 @@ def compute(
         cell_length
             The length of the edge of the cubic simulation cell,
             or an array of lengths of three cell vectors.
-        do_energy
-            if True, the energy is returned.
-        do_forces
-            if True, the atomic forces are returned.
-        do_press
-            if True, the force contribution to the pressure is returned.
+        nderiv
+            The order of derivatives to compute, either 0 (energy)
+            or 1 (energy, forces and pressure).
 
         Returns
         -------
@@ -84,23 +73,20 @@ def compute(
 
         # Compute all pairwise quantities, if needed with derivatives.
         for pairwise_term in self.pairwise_terms:
-            pairwise_term.compute_nlist(nlist, do_energy, do_forces | do_press)
+            pairwise_term.compute_nlist(nlist, nderiv)
 
         # Compute the totals
         results = []
-        if do_energy:
-            energy = nlist["energy"].sum()
-            results.append(energy)
-        if do_forces or do_press:
+        energy = nlist["energy"].sum()
+        results.append(energy)
+        if nderiv >= 1:
             nlist["gdelta"] = (nlist["gdist"] / nlist["dist"]).reshape(-1, 1) * nlist["delta"]
-            if do_forces:
-                atfrc = np.zeros(atpos.shape, dtype=float)
-                np.subtract.at(atfrc, nlist["iatom1"], nlist["gdelta"])
-                np.add.at(atfrc, nlist["iatom0"], nlist["gdelta"])
-                results.append(atfrc)
-            if do_press:
-                frc_press = -np.dot(nlist["gdist"], nlist["dist"]) / (3 * cell_lengths.prod())
-                results.append(frc_press)
+            atfrc = np.zeros(atpos.shape, dtype=float)
+            np.subtract.at(atfrc, nlist["iatom1"], nlist["gdelta"])
+            np.add.at(atfrc, nlist["iatom0"], nlist["gdelta"])
+            results.append(atfrc)
+            frc_press = -np.dot(nlist["gdist"], nlist["dist"]) / (3 * cell_lengths.prod())
+            results.append(frc_press)
 
         return results
 
diff --git a/src/tinyff/pairwise.py b/src/tinyff/pairwise.py
index 4a20c61..00407a6 100644
--- a/src/tinyff/pairwise.py
+++ b/src/tinyff/pairwise.py
@@ -29,23 +29,33 @@
 
 @attrs.define
 class PairwiseTerm:
-    def compute_nlist(
-        self, nlist: NDArray[NLIST_DTYPE], do_energy: bool = True, do_gdist: bool = False
-    ):
-        """Compute energies and derivatives and add them to the neighborlist."""
-        results = self.compute(nlist["dist"], do_energy, do_gdist)
-        if do_energy:
-            nlist["energy"] += results.pop(0)
-        if do_gdist:
+    def compute_nlist(self, nlist: NDArray[NLIST_DTYPE], nderiv: int = 0):
+        """Compute energies and derivatives and add them to the neighborlist.
+
+        Parameters
+        ----------
+        nlist
+            The neighborlist to which energies (and derivatives) must be added.
+        nderiv
+            The order of derivatives to compute, either 0 (energy)
+            or 1 (energy and its derivative).
+        """
+        results = self.compute(nlist["dist"], nderiv)
+        nlist["energy"] += results.pop(0)
+        if nderiv >= 1:
             nlist["gdist"] += results.pop(0)
 
-    def compute(
-        self,
-        dist: NDArray[float],
-        do_energy: bool = True,
-        do_gdist: bool = False,
-    ) -> list[NDArray]:
-        """Compute pair potential energy and its derivative towards distance."""
+    def compute(self, dist: NDArray[float], nderiv: int = 0) -> list[NDArray]:
+        """Compute pair potential energy and its derivative towards distance.
+
+        Parameters
+        ----------
+        dist
+            The interatomic distances.
+        nderiv
+            The order of derivatives to compute, either 0 (energy)
+            or 1 (energy and its derivative).
+        """
         raise NotImplementedError  # pragma: nocover
 
 
@@ -54,23 +64,17 @@ class LennardJones(PairwiseTerm):
     epsilon: float = attrs.field(default=1.0, converter=float)
     sigma: float = attrs.field(default=1.0, converter=float)
 
-    def compute(
-        self,
-        dist: NDArray[float],
-        do_energy: bool = True,
-        do_gdist: bool = False,
-    ) -> list[NDArray]:
+    def compute(self, dist: NDArray[float], nderiv: int = 0) -> list[NDArray]:
         """Compute pair potential energy and its derivative towards distance."""
         results = []
         dist = np.asarray(dist, dtype=float)
         x = self.sigma / dist
         x3 = x * x * x
         x6 = x3 * x3
-        if do_energy:
-            energy = (x6 - 1) * x6
-            energy *= 4 * self.epsilon
-            results.append(energy)
-        if do_gdist:
+        energy = (x6 - 1) * x6
+        energy *= 4 * self.epsilon
+        results.append(energy)
+        if nderiv >= 1:
             gdist = (x6 - 0.5) * x6 / dist
             gdist *= -48 * self.epsilon
             results.append(gdist)
@@ -86,14 +90,9 @@ class CutOffWrapper(PairwiseTerm):
 
     def __attrs_post_init__(self):
         """Post initialization changes."""
-        self.ecut, self.gcut = self.original.compute(self.rcut, do_gdist=True)
-
-    def compute(
-        self,
-        dist: NDArray[float],
-        do_energy: bool = True,
-        do_gdist: bool = False,
-    ) -> list[NDArray]:
+        self.ecut, self.gcut = self.original.compute(self.rcut, nderiv=1)
+
+    def compute(self, dist: NDArray[float], nderiv: int = 0) -> list[NDArray]:
         """Compute pair potential energy and its derivative towards distance."""
         dist = np.asarray(dist, dtype=float)
         mask = dist < self.rcut
@@ -101,28 +100,25 @@ def compute(
         if mask.ndim == 0:
             # Deal with non-array case
             if mask:
-                orig_results = self.original.compute(dist, do_energy, do_gdist)
-                if do_energy:
-                    energy = orig_results.pop(0)
-                    energy -= self.ecut + self.gcut * (dist - self.rcut)
-                    results.append(energy)
-                if do_gdist:
+                orig_results = self.original.compute(dist, nderiv)
+                energy = orig_results.pop(0)
+                energy -= self.ecut + self.gcut * (dist - self.rcut)
+                results.append(energy)
+                if nderiv >= 1:
                     gdist = orig_results.pop(0)
                     gdist -= self.gcut
                     results.append(gdist)
             else:
-                if do_energy:
-                    results.append(0.0)
-                if do_gdist:
+                results.append(0.0)
+                if nderiv >= 1:
                     results.append(0.0)
         else:
-            orig_results = self.original.compute(dist, do_energy, do_gdist)
-            if do_energy:
-                energy = orig_results.pop(0)
-                energy -= self.ecut + self.gcut * (dist - self.rcut)
-                energy *= mask
-                results.append(energy)
-            if do_gdist:
+            orig_results = self.original.compute(dist, nderiv)
+            energy = orig_results.pop(0)
+            energy -= self.ecut + self.gcut * (dist - self.rcut)
+            energy *= mask
+            results.append(energy)
+            if nderiv >= 1:
                 gdist = orig_results.pop(0)
                 gdist -= self.gcut
                 gdist *= mask
@@ -136,21 +132,15 @@ class CheapRepulsion(PairwiseTerm):
 
     rcut: float = attrs.field(converter=float, validator=attrs.validators.gt(0))
 
-    def compute(
-        self,
-        dist: NDArray[float],
-        do_energy: bool = True,
-        do_gdist: bool = False,
-    ) -> list[NDArray]:
+    def compute(self, dist: NDArray[float], nderiv: int = 0) -> list[NDArray]:
         """Compute pair potential energy and its derivative towards distance."""
         dist = np.asarray(dist, dtype=float)
         x = dist / self.rcut
         results = []
         common = (x - 1) * (x < 1)
-        if do_energy:
-            energy = common * common
-            results.append(energy)
-        if do_gdist:
+        energy = common * common
+        results.append(energy)
+        if nderiv >= 1:
             gdist = (2 / self.rcut) * common
             results.append(gdist)
         return results
diff --git a/tests/test_forcefield.py b/tests/test_forcefield.py
index b9af43e..6e488b7 100644
--- a/tests/test_forcefield.py
+++ b/tests/test_forcefield.py
@@ -39,9 +39,9 @@ def test_pairwise_force_field_two(nbuild):
     ff = ForceField([lj], nbuild=nbuild)
 
     # Compute and check against manual result
-    energy, forces, frc_press = ff.compute(atpos, cell_length, do_forces=True, do_press=True)
+    energy, forces, frc_press = ff.compute(atpos, cell_length, nderiv=1)
     d = np.linalg.norm(atpos[0] - atpos[1])
-    e, g = lj.compute(d, do_gdist=True)
+    e, g = lj.compute(d, nderiv=1)
     assert energy == pytest.approx(e)
     assert forces == pytest.approx(np.array([[g, 0.0, 0.0], [-g, 0.0, 0.0]]))
     assert frc_press == pytest.approx(-g * d / (3 * cell_length**3))
@@ -59,7 +59,7 @@ def test_pairwise_force_field_three(nbuild):
     ff = ForceField([lj], nbuild=nbuild)
 
     # Compute the energy, the forces and the force contribution pressure.
-    energy1, forces1, frc_press1 = ff.compute(atpos, cell_length, do_forces=True, do_press=True)
+    energy1, forces1, frc_press1 = ff.compute(atpos, cell_length, nderiv=1)
 
     # Compute the energy manually and compare.
     dists = [
@@ -115,7 +115,7 @@ def test_pairwise_force_field_fifteen(nbuild):
     ff = ForceField([lj], nbuild=nbuild)
 
     # Compute the energy, the forces and the force contribution to the pressure.
-    energy, forces1, frc_press1 = ff.compute(atpos, cell_length, do_forces=True, do_press=True)
+    energy, forces1, frc_press1 = ff.compute(atpos, cell_length, nderiv=1)
     assert energy < 0
 
     # Test forces with numdifftool
@@ -148,9 +148,9 @@ def test_superposition(nbuild_class, kwargs):
     ff_pp = ForceField([cr], nbuild=nbuild_class(rcut, **kwargs))
     ff_su = ForceField([lj, cr], nbuild=nbuild_class(rcut, **kwargs))
 
-    ener_lj, forces_lj, press_lj = ff_lj.compute(atpos, cell_length, do_forces=True, do_press=True)
-    ener_pp, forces_pp, press_pp = ff_pp.compute(atpos, cell_length, do_forces=True, do_press=True)
-    ener_su, forces_su, press_su = ff_su.compute(atpos, cell_length, do_forces=True, do_press=True)
+    ener_lj, forces_lj, press_lj = ff_lj.compute(atpos, cell_length, nderiv=1)
+    ener_pp, forces_pp, press_pp = ff_pp.compute(atpos, cell_length, nderiv=1)
+    ener_su, forces_su, press_su = ff_su.compute(atpos, cell_length, nderiv=1)
     assert ener_lj + ener_pp == pytest.approx(ener_su)
     assert forces_lj + forces_pp == pytest.approx(forces_su)
     assert press_lj + press_pp == pytest.approx(press_su)
diff --git a/tests/test_pairwise.py b/tests/test_pairwise.py
index 1d8ac01..a1af18c 100644
--- a/tests/test_pairwise.py
+++ b/tests/test_pairwise.py
@@ -28,7 +28,7 @@
 def test_lennard_jones_derivative():
     lj = LennardJones(2.5, 0.5)
     dist = np.linspace(0.4, 3.0, 50)
-    gdist1 = lj.compute(dist, do_energy=False, do_gdist=True)[0]
+    gdist1 = lj.compute(dist, nderiv=1)[1]
     gdist2 = nd.Derivative(lambda x: lj.compute(x)[0])(dist)
     assert gdist1 == pytest.approx(gdist2)
 
@@ -36,21 +36,21 @@ def test_lennard_jones_derivative():
 def test_lennard_jones_cut_derivative():
     lj = CutOffWrapper(LennardJones(2.5, 0.5), 3.5)
     dist = np.linspace(0.4, 5.0, 50)
-    gdist1 = lj.compute(dist, do_energy=False, do_gdist=True)[0]
+    gdist1 = lj.compute(dist, nderiv=1)[1]
     gdist2 = nd.Derivative(lambda x: lj.compute(x)[0])(dist)
     assert gdist1 == pytest.approx(gdist2)
 
 
 def test_lennard_jones_cut_zero_array():
     lj = CutOffWrapper(LennardJones(2.5, 0.5), 3.5)
-    e, g = lj.compute([5.0, 3.6], do_gdist=True)
+    e, g = lj.compute([5.0, 3.6], nderiv=1)
     assert (e == 0.0).all()
     assert (g == 0.0).all()
 
 
 def test_lennard_jones_cut_zero_scalar():
     lj = CutOffWrapper(LennardJones(2.5, 0.5), 3.5)
-    e, g = lj.compute(5.0, do_gdist=True)
+    e, g = lj.compute(5.0, nderiv=1)
     assert e == 0.0
     assert g == 0.0
 
@@ -58,15 +58,21 @@ def test_lennard_jones_cut_zero_scalar():
 def test_cheap_repulsion_derivative():
     cr = CheapRepulsion(2.5)
     dist = np.linspace(0.4, 3.0, 50)
-    gdist1 = cr.compute(dist, do_energy=False, do_gdist=True)[0]
+    gdist1 = cr.compute(dist, nderiv=1)[1]
     gdist2 = nd.Derivative(lambda x: cr.compute(x)[0])(dist)
     assert gdist1 == pytest.approx(gdist2)
 
 
 def test_cheap_repulsion_cutoff():
-    cr = CheapRepulsion(2.5)
+    rcut = 2.5
+    cr = CheapRepulsion(rcut)
     eps = 1e-13
-    assert abs(cr.compute(2.5 - 0.1)[0]) > eps
-    assert abs(cr.compute(2.5 - 0.1, do_energy=False, do_gdist=True)[0]) > eps
-    assert abs(cr.compute(2.5 - eps)[0]) < eps
-    assert abs(cr.compute(2.5 - eps, do_energy=False, do_gdist=True)[0]) < eps
+    e, g = cr.compute(rcut - 0.1, nderiv=1)
+    assert abs(e) > eps
+    assert abs(g) > eps
+    e, g = cr.compute(rcut - eps, nderiv=1)
+    assert abs(e) < eps
+    assert abs(g) < eps
+    e, g = cr.compute(rcut + 0.2, nderiv=1)
+    assert e == 0.0
+    assert g == 0.0