def setUp(self) -> None:
     self._potential = DisplacedEvenPowerPotential(equilibrium_separation=0.1, power=2, prefactor=0.5)
 def test_equilibrium_separation_negative_raises_error(self):
     with self.assertRaises(ConfigurationError):
         DisplacedEvenPowerPotential(equilibrium_separation=-0.3, power=2, prefactor=1.0)
class TestDisplacedEvenPowerPotential(TestCase):
    def setUp(self) -> None:
        self._potential = DisplacedEvenPowerPotential(equilibrium_separation=0.1, power=2, prefactor=0.5)

    def test_displacement_active_unit_behind_outside_potential_minimum_sphere_can_reach_sphere(self):
        height_potential_hill = 0.0006921428753625723
        self._potential._prefactor = 0.5 * 0.5 * 1.3
        # Active unit can climb potential hill without problem
        self.assertAlmostEqual(self._potential.displacement(0, [0.3, 0.05, -0.02], 0.3),
                               1.358290719101263, places=12)
        # Active unit cannot climb potential hill by far
        self.assertAlmostEqual(self._potential.displacement(1, [0.05, 0.3, -0.02], 0.0002),
                               0.2475214783762321, places=13)
        # Active unit can barely climb potential hill
        self.assertAlmostEqual(self._potential.displacement(
            2, [-0.02, 0.05, 0.3], height_potential_hill + 1.e-13),
                               0.3842621560389638, places=13)
        # Active unit can barely not climb potential hill
        self.assertAlmostEqual(self._potential.displacement(
            0, [0.3, -0.02, 0.05], height_potential_hill - 1.e-13),
                               0.2999994007887726, places=12)

    def test_displacement_active_unit_behind_outside_potential_minimum_sphere_cannnot_reach_sphere(self):
        # Test in all directions
        self._potential._prefactor = 0.5 * 2.1 * 1.1
        self.assertAlmostEqual(self._potential.displacement(0, [0.3, 0.1, 0.02], 0.4),
                               0.980898606235689, places=13)
        self._potential._prefactor = 0.5 * 0.4 * 0.4
        self.assertAlmostEqual(self._potential.displacement(1, [-0.1, 0.2, 0.0001], 0.002),
                               0.4379553878391659, places=13)
        self._potential._prefactor = 0.5
        self.assertAlmostEqual(self._potential.displacement(2, [0.09, -0.09, 0.001], 0.1),
                               0.5340601455693887, places=13)

    def test_displacement_active_unit_behind_inside_potential_minimum_sphere(self):
        height_potential_hill = 0.0000895627250851899
        self._potential._prefactor = 0.5 * 0.2 * 0.3
        # Active unit can climb potential without problem
        self.assertAlmostEqual(self._potential.displacement(0, [0.07, 0.03, -0.03], 0.1),
                               1.99445647542066, places=12)
        # Active unit cannot climb potential hill by far
        self.assertAlmostEqual(self._potential.displacement(1, [0.03, 0.07, -0.03], 0.000005),
                               0.004869943963535905, places=15)
        # Active unit can barely climb potential hill
        self.assertAlmostEqual(self._potential.displacement(
            2, [-0.03, 0.03, 0.07], height_potential_hill + 1.e-13),
                               0.1605558675719981, places=13)
        # Active unit can barely not climb potential hill
        self.assertAlmostEqual(self._potential.displacement(
            0, [0.07, -0.03, 0.03], height_potential_hill - 1.e-13),
                               0.06999843272252484, places=14)

    def test_displacement_active_unit_in_front_inside_potential_minimum_sphere(self):
        self._potential._prefactor = 0.5 * 1.3 * 0.7
        # Test in all directions
        self.assertAlmostEqual(self._potential.displacement(0, [-0.03, 0.04, 0.05], 0.1),
                               0.5351917072710099, places=13)
        self.assertAlmostEqual(self._potential.displacement(1, [0.04, -0.03, 0.05], 0.1),
                               0.5351917072710099, places=13)
        self.assertAlmostEqual(self._potential.displacement(2, [0.05, 0.04, -0.03], 0.1),
                               0.5351917072710099, places=13)

    def test_displacement_active_unit_in_front_outside_potential_minimum_sphere(self):
        self._potential._prefactor = 0.5 * 0.22 * 0.11
        # Test in all directions
        self.assertAlmostEqual(self._potential.displacement(0, [-0.01, 0.1, -0.3], 0.05),
                               2.110827419070795, places=12)
        self.assertAlmostEqual(self._potential.displacement(1, [0.1, -0.01, -0.3], 0.05),
                               2.110827419070795, places=12)
        self.assertAlmostEqual(self._potential.displacement(2, [-0.3, 0.1, -0.01], 0.05),
                               2.110827419070795, places=12)

    def test_derivative(self):
        self._potential._prefactor = 0.5 * 0.7 * 0.9
        # Test in all directions
        self.assertAlmostEqual(self._potential.derivative(0, [0.2, 0.1, -0.3]),
                               -0.0923250835190345, places=14)
        self.assertAlmostEqual(self._potential.derivative(1, [0.1, 0.2, -0.3]),
                               -0.0923250835190345, places=14)
        self.assertAlmostEqual(self._potential.derivative(2, [-0.3, 0.1, 0.2]),
                               -0.0923250835190345, places=14)

    def test_prefactor_negative_raises_error(self):
        with self.assertRaises(ConfigurationError):
            DisplacedEvenPowerPotential(equilibrium_separation=0.1, power=2, prefactor=-0.5)

    def test_prefactor_zero_raises_error(self):
        with self.assertRaises(ConfigurationError):
            DisplacedEvenPowerPotential(equilibrium_separation=0.1, power=2, prefactor=0.0)

    def test_power_zero_raises_error(self):
        with self.assertRaises(ConfigurationError):
            DisplacedEvenPowerPotential(equilibrium_separation=0.1, power=0, prefactor=1.0)

    def test_power_negative_raises_error(self):
        with self.assertRaises(ConfigurationError):
            DisplacedEvenPowerPotential(equilibrium_separation=0.1, power=-1, prefactor=1.0)

    def test_power_odd_raises_error(self):
        with self.assertRaises(ConfigurationError):
            DisplacedEvenPowerPotential(equilibrium_separation=0.1, power=1, prefactor=1.0)
        with self.assertRaises(ConfigurationError):
            DisplacedEvenPowerPotential(equilibrium_separation=0.1, power=3, prefactor=1.0)

    def test_equilibrium_separation_zero_raises_error(self):
        with self.assertRaises(ConfigurationError):
            DisplacedEvenPowerPotential(equilibrium_separation=0.0, power=2, prefactor=1.0)

    def test_equilibrium_separation_negative_raises_error(self):
        with self.assertRaises(ConfigurationError):
            DisplacedEvenPowerPotential(equilibrium_separation=-0.3, power=2, prefactor=1.0)
 def test_power_odd_raises_error(self):
     with self.assertRaises(ConfigurationError):
         DisplacedEvenPowerPotential(equilibrium_separation=0.1, power=1, prefactor=1.0)
     with self.assertRaises(ConfigurationError):
         DisplacedEvenPowerPotential(equilibrium_separation=0.1, power=3, prefactor=1.0)