def initialise( number_of_particles, temperature, box_length, init_conf, timestep_length=1e-14, mass=39.948, constants=[1.363e-134, 9.273e-78], forcefield=ff.lennard_jones, ): """Initialise the particle positions (this can be either as a square or random arrangement), velocities (based on the temperature defined, and calculate the initial forces/accelerations. Parameters ---------- number_of_particles: int Number of particles to simulate. temperature: float Initial temperature of the particles, in Kelvin. box_length: float Length of a single dimension of the simulation square, in Angstrom. init_conf: string, optional The way that the particles are initially positioned. Should be one of: - 'square' - 'random' timestep_length: float (optional) Length for each Velocity-Verlet integration step, in seconds. mass: float (optional) The mass of the particles being simulated. constants: float, array_like (optional) The values of the constants for the forcefield used. forcefield: function (optional) The particular forcefield to be used to find the energy and forces. Returns ------- System System information. """ from pylj import util system = util.System( number_of_particles, temperature, box_length, constants, forcefield, mass, init_conf=init_conf, timestep_length=timestep_length, ) v = np.random.rand(system.particles.size, 2, 12) v = np.sum(v, axis=2) - 6.0 mass_kg = mass * 1.6605e-27 v = v * np.sqrt(1.3806e-23 * system.init_temp / mass_kg) v = v - np.average(v) system.particles["xvelocity"] = v[:, 0] system.particles["yvelocity"] = v[:, 1] return system
def initialise(number_of_particles, temperature, box_length, init_conf): """Initialise the particle positions (this can be either as a square or random arrangement), velocities (based on the temperature defined, and calculate the initial forces/accelerations. Parameters ---------- number_of_particles: int Number of particles to simulate. temperature: float Initial temperature of the particles, in Kelvin. box_length: float Length of a single dimension of the simulation square, in Angstrom. init_conf: string, optional The way that the particles are initially positioned. Should be one of: - 'square' - 'random' Returns ------- System System information. """ system = util.System(number_of_particles, temperature, box_length, init_conf=init_conf) system.particles['xvelocity'] = 0 system.particles['yvelocity'] = 0 return system
def test_system_too_small(self): with self.assertRaises(AttributeError) as context: util.System( 2, 300, 2, mass=39.948, constants=[1.363e-134, 9.273e-78], forcefield=ff.lennard_jones, ) self.assertTrue( "With a box length of 2 the cell is too small to " "really hold more than one particle." in str(context.exception))
def test_system_too_big(self): with self.assertRaises(AttributeError) as context: util.System( 2, 300, 1000, mass=39.948, constants=[1.363e-134, 9.273e-78], forcefield=ff.lennard_jones, ) self.assertTrue("With a box length of 1000 the particles are probably " "too small to be seen in the viewer. Try something " "(much) less than 600." in str(context.exception))
def initialise( number_of_particles, temperature, box_length, init_conf, mass=39.948, constants=[1.363e-134, 9.273e-78], forcefield=ff.lennard_jones, ): """Initialise the particle positions (this can be either as a square or random arrangement), velocities (based on the temperature defined, and # calculate the initial forces/accelerations. Parameters ---------- number_of_particles: int Number of particles to simulate. temperature: float Initial temperature of the particles, in Kelvin. box_length: float Length of a single dimension of the simulation square, in Angstrom. init_conf: string, optional The way that the particles are initially positioned. Should be one of: - 'square' - 'random' mass: float (optional) The mass of the particles being simulated. constants: float, array_like (optional) The values of the constants for the forcefield used. forcefield: function (optional) The particular forcefield to be used to find the energy and forces. Returns ------- System System information. """ from pylj import util system = util.System( number_of_particles, temperature, box_length, constants, forcefield, mass, init_conf=init_conf, ) system.particles["xvelocity"] = 0 system.particles["yvelocity"] = 0 return system
def test_system_init_conf(self): with self.assertRaises(NotImplementedError) as context: util.System( 2, 300, 100, init_conf="horseradish", mass=39.948, constants=[1.363e-134, 9.273e-78], forcefield=ff.lennard_jones, ) self.assertTrue("The initial configuration type horseradish is not " "recognised. Available options are: square or " "random" in str(context.exception))
def initialise(number_of_particles, temperature, box_length, init_conf, timestep_length=1e-14): """Initialise the particle positions (this can be either as a square or random arrangement), velocities (based on the temperature defined, and calculate the initial forces/accelerations. Parameters ---------- number_of_particles: int Number of particles to simulate. temperature: float Initial temperature of the particles, in Kelvin. box_length: float Length of a single dimension of the simulation square, in Angstrom. init_conf: string, optional The way that the particles are initially positioned. Should be one of: - 'square' - 'random' timestep_length: float (optional) Length for each Velocity-Verlet integration step, in seconds. Returns ------- System System information. """ system = util.System(number_of_particles, temperature, box_length, init_conf=init_conf, timestep_length=timestep_length) v = np.random.rand(system.particles.size, 2) - 0.5 v2sum = np.average(np.square(v)) v = (v - np.average(v)) * np.sqrt(2 * system.init_temp / (v2sum)) system.particles['xvelocity'] = v[:, 0] system.particles['yvelocity'] = v[:, 1] system.particles, system.distances, system.forces = comp.compute_forces( system.particles, system.distances, system.forces, system.box_length) return system
def test_system_square(self): a = util.System( 2, 300, 8, mass=39.948, constants=[1.363e-134, 9.273e-78], forcefield=ff.lennard_jones, ) assert_equal(a.number_of_particles, 2) assert_equal(a.init_temp, 300) assert_almost_equal(a.box_length * 1e10, 8) assert_almost_equal(a.timestep_length, 1e-14) assert_almost_equal(a.particles["xposition"] * 1e10, [2, 2]) assert_almost_equal(a.particles["yposition"] * 1e10, [2, 6]) assert_almost_equal(a.initial_particles["xposition"] * 1e10, [2, 2]) assert_almost_equal(a.initial_particles["yposition"] * 1e10, [2, 6]) assert_almost_equal(a.cut_off * 1e10, 4.0) assert_equal(a.distances.size, 1) assert_equal(a.forces.size, 1) assert_equal(a.energies.size, 1)
def test_system_random(self): a = util.System( 2, 300, 8, init_conf="random", mass=39.948, constants=[1.363e-134, 9.273e-78], forcefield=ff.lennard_jones, ) assert_equal(a.number_of_particles, 2) assert_equal(a.init_temp, 300) assert_almost_equal(a.box_length * 1e10, 8) assert_almost_equal(a.timestep_length, 1e-14) self.assertTrue(0 <= a.particles["xposition"][0] * 1e10 <= 8) self.assertTrue(0 <= a.particles["yposition"][0] * 1e10 <= 8) self.assertTrue(0 <= a.particles["xposition"][1] * 1e10 <= 8) self.assertTrue(0 <= a.particles["yposition"][1] * 1e10 <= 8) assert_almost_equal(a.cut_off * 1e10, 4.0) assert_equal(a.distances.size, 1) assert_equal(a.forces.size, 1) assert_equal(a.energies.size, 1)