def test_ljc_get_energy_LJ38(self) -> None: lj38 = Cluster(cost=0.0, molecules=[ Molecule(coordinates=np.array([c]), particle_names=["LJ"]) for c in self.lj38_coordinates ]) fast_potential = LJcPotential(38) # Check that both potentials calculate the same correct energy for the LJ38 minimum e_fast_38 = fast_potential.get_energy(lj38) self.assertAlmostEqual( -173.928427, e_fast_38, places=6) # 6dp accuracy as this is reported online self.assertEqual(self.ref_potential.get_energy(lj38), e_fast_38)
def test_ljc_get_energy_0(self) -> None: fast_potential = LJcPotential(2) c1 = Cluster(cost=0.0, molecules=[ Molecule(coordinates=np.array([[0.0, 0.0, 0.0]]), particle_names=["LJ"]), Molecule(coordinates=np.array([[1.0, 0.0, 0.0]]), particle_names=["LJ"]) ]) # First we check that we get U=0 at r=1 and both implementations give the same result e_fast_0 = fast_potential.get_energy(c1) self.assertEqual(0.0, e_fast_0) self.assertEqual(self.ref_potential.get_energy(c1, ), e_fast_0)
def test_ljc_get_energy_minimum(self) -> None: fast_potential = LJcPotential(2) c1 = Cluster(cost=0.0, molecules=[ Molecule(coordinates=np.array([[0.0, 0.0, 0.0]]), particle_names=["LJ"]), Molecule(coordinates=np.array( [[2**(1. / 6.0), 0.0, 0.0]]), particle_names=["LJ"]) ]) ref_energy = self.ref_potential.get_energy(c1) test_energy = fast_potential.get_energy(c1) self.assertEqual(ref_energy, test_energy)
def test_quench_run(self) -> None: self.log.info("Starting quench client") potential = LJcPotential(2) # noinspection PyTypeCheckers quencher = QuenchClient(potential, URI=self.uri, max_quenches=1) with self.assertRaises(SystemExit): quencher.run()
def test_ljc_minimizer(self) -> None: """Test that the minimizer returns the expected result""" fast_potential = LJcPotential(2) c1 = Cluster(cost=0.0, molecules=[ Molecule(coordinates=np.array([[0.0, 0.0, 0.0]]), particle_names=["LJ"]), Molecule(coordinates=np.array([[1.0, 0.0, 0.0]]), particle_names=["LJ"]) ]) min_ljc_small = fast_potential.minimize(cluster=c1) pos = min_ljc_small.get_particle_positions() coords = pos[0] min_dist_2_part = np.linalg.norm(coords[0] - coords[1]) self.assertAlmostEqual((2**(1. / 6.)), min_dist_2_part)
def test_quench_run_bad(self) -> None: potential = LJcPotential(2) self.log.info("Starting bad quench client") # noinspection PyTypeChecker quencher = QuenchClient(potential, URI=self.uri, max_quenches=7) # This is expected to fail because the server is set up to pass a # bad job description to the quencher after some time with self.assertRaises(ClientError): quencher.run()
def test_ljc_get_jacobian_1(self) -> None: fast_potential = LJcPotential(2) c1 = Cluster(cost=0.0, molecules=[ Molecule(coordinates=np.array([[0.0, 0.0, 0.0]]), particle_names=["LJ"]), Molecule(coordinates=np.array( [[2**(1 / 6.), 0.0, 0.0]]), particle_names=["LJ"]) ]) test_jac = fast_potential.get_jacobian( c1.get_particle_positions()[0].flatten()) # print(ref_jac, test_jac) self.assertEqual( np.array([-12.0, 0.0, 0.0, 12.0, 0.0, 0.0]).all(), test_jac.all())
def test_MC_step(self): c1 = Cluster(molecules=[ Molecule(coordinates=np.array([[0.0, 0.0, 0.0]]), particle_names=["LJ"]), Molecule(coordinates=np.array([[1.0, 1.0, 1.0]]), particle_names=["LJ"]), Molecule(coordinates=np.array([[1.0, -1.0, 1.0]]), particle_names=["LJ"]), Molecule(coordinates=np.array([[-1.0, 1.0, 1.0]]), particle_names=["LJ"]), Molecule(coordinates=np.array([[-1.0, -1.0, 1.0]]), particle_names=["LJ"]) ], cost=0.0) pot = LJcPotential(5) print(pot.get_energy(c1)) mc = MonteCarlo(potential=pot, temperature=10.0) mc.run(c1, 5) print(pot.get_energy(c1))
def test_ljc_jacobian(self) -> None: fast_potential = LJcPotential(38) lj38 = Cluster(cost=0.0, molecules=[ Molecule(coordinates=np.array([c]), particle_names=["LJ"]) for c in self.lj38_coordinates ]) lj38_minimum = fast_potential.minimize(lj38) coords = lj38_minimum.get_particle_positions() coords = coords[0] lj38_min_jac = fast_potential.get_jacobian(coords.flatten()) try: np.testing.assert_allclose(np.zeros(shape=38 * 3), lj38_min_jac, atol=0.001) except AssertionError: print(lj38_min_jac) print( "This is expected to be close to 0 as it is close to a minimum" ) self.fail("Calculated jacobian not close to expected") # Check that both classes return the same jacobian ref_jac = self.ref_potential.get_jacobian(coordinates=coords.flatten()) try: np.testing.assert_allclose(ref_jac, lj38_min_jac, atol=0.001) except AssertionError: print(lj38_min_jac, ref_jac) print("C implementation and pure python should return the same") self.fail("Calculated jacobian not close to expected")
def spawn_client(log): LJ_pot = LJcPotential() with open("example.uri") as f: uri = f.read().strip() quencher = QuenchClient(potential=LJ_pot, URI=uri, max_quenches=250, log=log) quencher.run()
def test_a_quench_init(self) -> None: potential = LJcPotential(1) # noinspection PyTypeChecker quencher = QuenchClient(potential, URI=self.uri) self.assertIsInstance(quencher, QuenchClient) # Check that providing no URI raises the correct error with self.assertRaises(AssertionError): # noinspection PyTypeChecker QuenchClient(potential) # Check that uri_from_file works uri = quencher.uri_from_file(self.uri) self.assertIsInstance(uri, str)
def accepted(self, new_cluster: Cluster, old_cluster: Cluster): dU = new_cluster.cost - old_cluster.cost if dU < 0.0: return True p = np.random.uniform() p_acc = np.exp(-dU / self.T) return p_acc > p if __name__ == "__main__": pot = LJcPotential(6) MC = MonteCarlo(potential=pot, temperature=0.1, update_steps=101, move_classes=[RandomSingleTranslation()]) c1 = Cluster(molecules=[ Molecule(coordinates=np.array([[0.0, 0.0, 0.0]]), particle_names=["LJ"]), Molecule(coordinates=np.array([[1.0, 1.0, 1.0]]), particle_names=["LJ"]), Molecule(coordinates=np.array([[1.0, -1.0, 1.0]]), particle_names=["LJ"]), Molecule(coordinates=np.array([[-1.0, 1.0, 1.0]]), particle_names=["LJ"]), Molecule(coordinates=np.array([[-1.0, -1.0, 1.0]]),