def check_global(self, N, kT, steps, v_minmax, n_bins, error_tol, recalc_forces): """ Test Langevin/Brownian dynamics velocity distribution with global kT and gamma. Parameters ---------- N : :obj:`int` Number of particles. kT : :obj:`float` Global temperature. steps : :obj:`int` Number of sampling steps. v_minmax : :obj:`float` Velocity range. n_bins : :obj:`int` Number of bins. error_tol : :obj:`float` Error tolerance. recalc_forces : :obj:`bool` True if the forces should be recalculated after every step. """ system = self.system # Place particles system.part.add(pos=np.random.random((N, 3))) # Enable rotation if compiled in if espressomd.has_features("ROTATION"): system.part[:].rotation = [1, 1, 1] # Warmup system.integrator.run(20) vel_obs = ParticleVelocities(ids=system.part[:].id) vel_acc = TimeSeries(obs=vel_obs) system.auto_update_accumulators.add(vel_acc) if espressomd.has_features("ROTATION"): omega_obs = ParticleBodyAngularVelocities(ids=system.part[:].id) omega_acc = TimeSeries(obs=omega_obs) system.auto_update_accumulators.add(omega_acc) # Sampling v_stored = np.zeros((steps, N, 3)) omega_stored = np.zeros((steps, N, 3)) for i in range(steps): system.integrator.run(1, recalc_forces=recalc_forces) v_stored[i] = system.part[:].v if espressomd.has_features("ROTATION"): omega_stored[i] = system.part[:].omega_body vel = vel_acc.time_series().reshape((-1, 3)) self.check_velocity_distribution(vel, v_minmax, n_bins, error_tol, kT) if espressomd.has_features("ROTATION"): omega = omega_acc.time_series().reshape((-1, 3)) self.check_velocity_distribution(omega, v_minmax, n_bins, error_tol, kT)
def check_noise_correlation(self, kT, steps, delta): """Test the Langevin/Brownian noise is uncorrelated. Parameters ---------- kT : :obj:`float` Global temperature. steps : :obj:`int` Number of sampling steps. delta : :obj:`float` Error tolerance. """ system = self.system vel_obs = ParticleVelocities(ids=system.part[:].id) vel_series = TimeSeries(obs=vel_obs) system.auto_update_accumulators.add(vel_series) if espressomd.has_features("ROTATION"): system.part[:].rotation = (1, 1, 1) omega_obs = ParticleBodyAngularVelocities(ids=system.part[:].id) omega_series = TimeSeries(obs=omega_obs) system.auto_update_accumulators.add(omega_series) system.integrator.run(steps) # test translational noise correlation vel = np.array(vel_series.time_series()) for ind in range(2): for i in range(3): for j in range(i, 3): corrcoef = np.dot(vel[:, ind, i], vel[:, ind, j]) / steps / kT if i == j: self.assertAlmostEqual(corrcoef, 1.0, delta=delta) else: self.assertAlmostEqual(corrcoef, 0.0, delta=delta) # test rotational noise correlation if espressomd.has_features("ROTATION"): omega = np.array(omega_series.time_series()) for ind in range(2): for i in range(3): for j in range(3): corrcoef = np.dot(omega[:, ind, i], omega[:, ind, j]) / steps / kT if i == j: self.assertAlmostEqual(corrcoef, 1.0, delta=delta) else: self.assertAlmostEqual(corrcoef, 0.0, delta=delta) # translational and angular velocities should be # independent corrcoef = np.dot(vel[:, ind, i], omega[:, ind, j]) / steps / kT self.assertAlmostEqual(corrcoef, 0.0, delta=delta)
def check_per_particle(self, N, kT, gamma_local, steps, v_minmax, n_bins, error_tol): """ Test Langevin/Brownian dynamics velocity distribution with global and particle-specific kT/gamma. Covers all combinations of particle specific-gamma and temp set or not set. Parameters ---------- N : :obj:`int` Number of particles. kT : :obj:`float` Global temperature. gamma_local : :obj:`float` Per-particle gamma. steps : :obj:`int` Number of sampling steps. v_minmax : :obj:`float` Velocity range. n_bins : :obj:`int` Number of bins. error_tol : :obj:`float` Error tolerance. """ system = self.system system.part.add(pos=np.random.random((N, 3))) if espressomd.has_features("ROTATION"): system.part[:].rotation = [1, 1, 1] if espressomd.has_features("PARTICLE_ANISOTROPY"): gamma_local = 3 * [gamma_local] # Set different gamma on 2nd half of particles system.part[N // 2:].gamma = gamma_local system.integrator.run(50) vel_obs = ParticleVelocities(ids=system.part[:].id) vel_acc = TimeSeries(obs=vel_obs) system.auto_update_accumulators.add(vel_acc) if espressomd.has_features("ROTATION"): omega_obs = ParticleBodyAngularVelocities(ids=system.part[:].id) omega_acc = TimeSeries(obs=omega_obs) system.auto_update_accumulators.add(omega_acc) system.integrator.run(steps) vel = vel_acc.time_series().reshape((-1, 3)) self.check_velocity_distribution(vel, v_minmax, n_bins, error_tol, kT) if espressomd.has_features("ROTATION"): omega = omega_acc.time_series().reshape((-1, 3)) self.check_velocity_distribution(omega, v_minmax, n_bins, error_tol, kT)
def test_08__noise_correlation(self): """Checks that the Brownian noise is uncorrelated""" system = self.system system.part.clear() system.time_step = 0.01 system.cell_system.skin = 0.1 system.part.add(id=(0, 1), pos=np.zeros((2, 3))) vel_obs = ParticleVelocities(ids=system.part[:].id) vel_series = TimeSeries(obs=vel_obs) system.auto_update_accumulators.add(vel_series) if espressomd.has_features("ROTATION"): system.part[:].rotation = (1, 1, 1) omega_obs = ParticleBodyAngularVelocities(ids=system.part[:].id) omega_series = TimeSeries(obs=omega_obs) system.auto_update_accumulators.add(omega_series) kT = 3.2 system.thermostat.set_brownian(kT=kT, gamma=2.1, seed=17) steps = int(1e4) system.integrator.run(steps) system.auto_update_accumulators.clear() # test translational noise correlation vel = np.array(vel_series.time_series()) for ind in range(2): for i in range(3): for j in range(i, 3): corrcoef = np.dot(vel[:, ind, i], vel[:, ind, j]) / steps / kT if i == j: self.assertAlmostEqual(corrcoef, 1.0, delta=0.04) else: self.assertLessEqual(np.abs(corrcoef), 0.04) # test rotational noise correlation if espressomd.has_features("ROTATION"): omega = np.array(omega_series.time_series()) for ind in range(2): for i in range(3): for j in range(3): corrcoef = np.dot(omega[:, ind, i], omega[:, ind, j]) / steps / kT if i == j: self.assertAlmostEqual(corrcoef, 1.0, delta=0.04) else: self.assertLessEqual(np.abs(corrcoef), 0.04) # translational and angular velocities should be # independent corrcoef = np.dot(vel[:, ind, i], omega[:, ind, j]) / steps / kT self.assertLessEqual(np.abs(corrcoef), 0.04)
def test_time_series(self): """Check that accumulator results are the same as the respective numpy result. """ system = espressomd.System(box_l=3 * [1.]) system.part.add(pos=np.random.random((N_PART, 3))) obs = ParticlePositions(ids=system.part[:].id) time_series = TimeSeries(obs=obs) positions = [] for _ in range(10): pos = np.random.random((N_PART, 3)) positions.append(pos) system.part[:].pos = pos time_series.update() for result, expected in zip(time_series.time_series(), positions): np.testing.assert_array_equal( np.array(result).reshape((N_PART, 3)), expected) time_series.clear() self.assertEqual(len(time_series.time_series()), 0)